From d3f6ca24c889b113b2a19d33a3e7931502f7a12a Mon Sep 17 00:00:00 2001 From: Evgeniy Alekseev Date: Sun, 20 Aug 2023 17:03:46 +0300 Subject: [PATCH] review exception raise In some cases for better readability of logs, exceptions are now raised without parent exception stacktrace. Also updated docs and contributing guidelines --- CONTRIBUTING.md | 8 +++++++- .../application/application/application_packages.py | 6 ++++++ src/ahriman/application/handlers/handler.py | 6 +++--- src/ahriman/application/handlers/search.py | 2 +- src/ahriman/application/handlers/users.py | 3 +++ src/ahriman/application/lock.py | 4 ++-- src/ahriman/core/alpm/remote/aur.py | 7 +++++-- src/ahriman/core/alpm/remote/official.py | 7 +++++-- src/ahriman/core/alpm/remote/official_syncdb.py | 5 ++++- src/ahriman/core/auth/oauth.py | 2 +- src/ahriman/core/gitremote/remote_pull.py | 5 ++++- src/ahriman/core/gitremote/remote_push.py | 5 ++++- src/ahriman/core/report/report.py | 4 ++-- src/ahriman/core/report/telegram.py | 3 +++ src/ahriman/core/status/watcher.py | 8 ++++---- src/ahriman/core/support/pkgbuild/keyring_generator.py | 3 +++ src/ahriman/core/triggers/trigger_loader.py | 8 ++++---- src/ahriman/core/upload/upload.py | 4 ++-- src/ahriman/core/util.py | 4 ++-- src/ahriman/models/package.py | 9 ++++++--- src/ahriman/models/repository_paths.py | 2 +- src/ahriman/models/result.py | 2 +- src/ahriman/web/middlewares/exception_handler.py | 3 +++ src/ahriman/web/views/base.py | 2 +- src/ahriman/web/views/service/pgp.py | 2 +- src/ahriman/web/views/service/upload.py | 5 +++-- src/ahriman/web/views/status/logs.py | 6 +++--- src/ahriman/web/views/status/package.py | 6 +++--- src/ahriman/web/views/status/packages.py | 2 +- src/ahriman/web/views/status/status.py | 2 +- src/ahriman/web/views/user/login.py | 4 ++-- src/ahriman/web/views/user/logout.py | 1 + 32 files changed, 92 insertions(+), 48 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e9ae316b..8ab42419 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -46,7 +46,7 @@ Again, the most checks can be performed by `make check` command, though some add int: result Raises: - RuntimeException: a local function error occurs + RuntimeError: a local function error occurs Examples: Very informative example how to use this function, e.g.:: @@ -130,6 +130,12 @@ Again, the most checks can be performed by `make check` command, though some add * Configuration interactions must go through `ahriman.core.configuration.Configuration` class instance. * In case if class load requires some actions, it is recommended to create class method which can be used for class instantiating. * The code must follow the exception safety, unless it is explicitly asked by end user. It means that most exceptions must be handled and printed to log, no other actions must be done (e.g. raising another exception). +* Exceptions without parameters should be raised without parentheses, e.g.: + + ```python + raise RuntimeError + ``` + * For the external command `ahriman.core.util.check_output` function must be used. * Every temporary file/directory must be removed at the end of processing, no matter what. The `tempfile` module provides good ways to do it. * Import order must be the following: diff --git a/src/ahriman/application/application/application_packages.py b/src/ahriman/application/application/application_packages.py index 8c19aee7..7aa3884f 100644 --- a/src/ahriman/application/application/application_packages.py +++ b/src/ahriman/application/application/application_packages.py @@ -73,6 +73,9 @@ class ApplicationPackages(ApplicationProperties): Args: source(str): path to local directory + + Raises: + UnknownPackageError: if specified package is unknown or doesn't exist """ local_dir = Path(source) if not local_dir.is_dir(): @@ -110,6 +113,9 @@ class ApplicationPackages(ApplicationProperties): Args: source(str): remote URL of the package archive + + Raises: + UnknownPackageError: if specified package is unknown or doesn't exist """ dst = self.repository.paths.packages / Path(source).name # URL is path, is not it? # timeout=None to suppress pylint warns. Also suppress bandit warnings diff --git a/src/ahriman/application/handlers/handler.py b/src/ahriman/application/handlers/handler.py index e3b700cb..28744aaf 100644 --- a/src/ahriman/application/handlers/handler.py +++ b/src/ahriman/application/handlers/handler.py @@ -61,7 +61,7 @@ class Handler: list[str]: list of architectures for which tree is created Raises: - MissingArchitecture: if no architecture set and automatic detection is not allowed or failed + MissingArchitectureError: if no architecture set and automatic detection is not allowed or failed """ if not cls.ALLOW_AUTO_ARCHITECTURE_RUN and args.architecture is None: # for some parsers (e.g. config) we need to run with specific architecture @@ -118,7 +118,7 @@ class Handler: int: 0 on success, 1 otherwise Raises: - MultipleArchitectures: if more than one architecture supplied and no multi architecture supported + MultipleArchitecturesError: if more than one architecture supplied and no multi architecture supported """ architectures = cls.architectures_extract(args) @@ -164,4 +164,4 @@ class Handler: ExitCode: if result is empty and check is enabled """ if enabled and predicate: - raise ExitCode() + raise ExitCode diff --git a/src/ahriman/application/handlers/search.py b/src/ahriman/application/handlers/search.py index 915b30d1..6fabcb89 100644 --- a/src/ahriman/application/handlers/search.py +++ b/src/ahriman/application/handlers/search.py @@ -81,7 +81,7 @@ class Search(Handler): list[AURPackage]: sorted list for packages Raises: - InvalidOption: if search fields is not in list of allowed ones + OptionError: if search fields is not in list of allowed ones """ if sort_by not in Search.SORT_FIELDS: raise OptionError(sort_by) diff --git a/src/ahriman/application/handlers/users.py b/src/ahriman/application/handlers/users.py index 1c133965..d8cd4238 100644 --- a/src/ahriman/application/handlers/users.py +++ b/src/ahriman/application/handlers/users.py @@ -72,6 +72,9 @@ class Users(Handler): Returns: User: built user descriptor + + Raises: + PasswordError: password input is invalid """ def read_password() -> str: first_password = getpass.getpass() diff --git a/src/ahriman/application/lock.py b/src/ahriman/application/lock.py index d2eb22d0..a2724673 100644 --- a/src/ahriman/application/lock.py +++ b/src/ahriman/application/lock.py @@ -106,14 +106,14 @@ class Lock(LazyLogging): create lock file Raises: - DuplicateRun: if lock exists and no force flag supplied + DuplicateRunError: if lock exists and no force flag supplied """ if self.path is None: return try: self.path.touch(exist_ok=self.force) except FileExistsError: - raise DuplicateRunError() + raise DuplicateRunError from None def watch(self) -> None: """ diff --git a/src/ahriman/core/alpm/remote/aur.py b/src/ahriman/core/alpm/remote/aur.py index bff37084..771c3997 100644 --- a/src/ahriman/core/alpm/remote/aur.py +++ b/src/ahriman/core/alpm/remote/aur.py @@ -83,7 +83,7 @@ class AUR(Remote): list[AURPackage]: list of parsed packages Raises: - InvalidPackageInfo: for error API response + PackageInfoError: for error API response """ response_type = response["type"] if response_type == "error": @@ -142,12 +142,15 @@ class AUR(Remote): Returns: AURPackage: package which match the package name + + Raises: + UnknownPackageError: package doesn't exist """ packages = self.make_request("info", package_name) try: return next(package for package in packages if package.name == package_name) except StopIteration: - raise UnknownPackageError(package_name) + raise UnknownPackageError(package_name) from None def package_search(self, *keywords: str, pacman: Pacman) -> list[AURPackage]: """ diff --git a/src/ahriman/core/alpm/remote/official.py b/src/ahriman/core/alpm/remote/official.py index f627df7c..d64d1c68 100644 --- a/src/ahriman/core/alpm/remote/official.py +++ b/src/ahriman/core/alpm/remote/official.py @@ -85,7 +85,7 @@ class Official(Remote): list[AURPackage]: list of parsed packages Raises: - InvalidPackageInfo: for error API response + PackageInfoError: for error API response """ if not response["valid"]: raise PackageInfoError("API validation error") @@ -127,12 +127,15 @@ class Official(Remote): Returns: AURPackage: package which match the package name + + Raises: + UnknownPackageError: package doesn't exist """ packages = self.make_request(package_name, by="name") try: return next(package for package in packages if package.name == package_name) except StopIteration: - raise UnknownPackageError(package_name) + raise UnknownPackageError(package_name) from None def package_search(self, *keywords: str, pacman: Pacman) -> list[AURPackage]: """ diff --git a/src/ahriman/core/alpm/remote/official_syncdb.py b/src/ahriman/core/alpm/remote/official_syncdb.py index 3dd0a44a..f310042b 100644 --- a/src/ahriman/core/alpm/remote/official_syncdb.py +++ b/src/ahriman/core/alpm/remote/official_syncdb.py @@ -48,8 +48,11 @@ class OfficialSyncdb(Official): Returns: AURPackage: package which match the package name + + Raises: + UnknownPackageError: package doesn't exist """ try: return next(AURPackage.from_pacman(package) for package in pacman.package_get(package_name)) except StopIteration: - raise UnknownPackageError(package_name) + raise UnknownPackageError(package_name) from None diff --git a/src/ahriman/core/auth/oauth.py b/src/ahriman/core/auth/oauth.py index f1c1fbeb..a12c5386 100644 --- a/src/ahriman/core/auth/oauth.py +++ b/src/ahriman/core/auth/oauth.py @@ -81,7 +81,7 @@ class OAuth(Mapping): type[aioauth_client.OAuth2Client]: loaded provider type Raises: - InvalidOption: in case if invalid OAuth provider name supplied + OptionError: in case if invalid OAuth provider name supplied """ provider: type[aioauth_client.OAuth2Client] = getattr(aioauth_client, name) try: diff --git a/src/ahriman/core/gitremote/remote_pull.py b/src/ahriman/core/gitremote/remote_pull.py index 2c0e1c07..f5d5718a 100644 --- a/src/ahriman/core/gitremote/remote_pull.py +++ b/src/ahriman/core/gitremote/remote_pull.py @@ -104,9 +104,12 @@ class RemotePull(LazyLogging): def run(self) -> None: """ run git pull action + + Raises: + GitRemoteError: pull processing error """ try: self.repo_clone() except Exception: self.logger.exception("git pull failed") - raise GitRemoteError() + raise GitRemoteError diff --git a/src/ahriman/core/gitremote/remote_push.py b/src/ahriman/core/gitremote/remote_push.py index 769c131e..22149608 100644 --- a/src/ahriman/core/gitremote/remote_push.py +++ b/src/ahriman/core/gitremote/remote_push.py @@ -118,6 +118,9 @@ class RemotePush(LazyLogging): Args: result(Result): build result + + Raises: + GitRemoteError: push processing error """ try: with TemporaryDirectory(ignore_cleanup_errors=True) as dir_name: @@ -127,4 +130,4 @@ class RemotePush(LazyLogging): commit_author=self.commit_author) except Exception: self.logger.exception("git push failed") - raise GitRemoteError() + raise GitRemoteError diff --git a/src/ahriman/core/report/report.py b/src/ahriman/core/report/report.py index 94a7d361..b4d5862d 100644 --- a/src/ahriman/core/report/report.py +++ b/src/ahriman/core/report/report.py @@ -116,10 +116,10 @@ class Report(LazyLogging): packages(list[Package]): list of packages to generate report Raises: - ReportFailed: in case of any report unmatched exception + ReportError: in case of any report unmatched exception """ try: self.generate(packages, result) except Exception: self.logger.exception("report generation failed") - raise ReportError() + raise ReportError diff --git a/src/ahriman/core/report/telegram.py b/src/ahriman/core/report/telegram.py index 6a5b0610..3ae8e838 100644 --- a/src/ahriman/core/report/telegram.py +++ b/src/ahriman/core/report/telegram.py @@ -89,6 +89,9 @@ class Telegram(Report, JinjaTemplate): Args: packages(list[Package]): list of packages to generate report result(Result): build result + + Raises: + ValueError: impossible to split message by chunks """ if not result.success: return diff --git a/src/ahriman/core/status/watcher.py b/src/ahriman/core/status/watcher.py index 2ca9269a..9816c4ea 100644 --- a/src/ahriman/core/status/watcher.py +++ b/src/ahriman/core/status/watcher.py @@ -133,12 +133,12 @@ class Watcher(LazyLogging): tuple[Package, BuildStatus]: package and its status Raises: - UnknownPackage: if no package found + UnknownPackageError: if no package found """ try: return self.known[package_base] except KeyError: - raise UnknownPackageError(package_base) + raise UnknownPackageError(package_base) from None def package_remove(self, package_base: str) -> None: """ @@ -161,13 +161,13 @@ class Watcher(LazyLogging): package(Package | None): optional package description. In case if not set current properties will be used Raises: - UnknownPackage: if no package found + UnknownPackageError: if no package found """ if package is None: try: package, _ = self.known[package_base] except KeyError: - raise UnknownPackageError(package_base) + raise UnknownPackageError(package_base) from None full_status = BuildStatus(status) self.known[package_base] = (package, full_status) self.database.package_update(package, full_status) diff --git a/src/ahriman/core/support/pkgbuild/keyring_generator.py b/src/ahriman/core/support/pkgbuild/keyring_generator.py index c9d90f45..3374eb2b 100644 --- a/src/ahriman/core/support/pkgbuild/keyring_generator.py +++ b/src/ahriman/core/support/pkgbuild/keyring_generator.py @@ -140,6 +140,9 @@ class KeyringGenerator(PkgbuildGenerator): Args: source_path(Path): destination of the file content + + Raises: + PkgbuildGeneratorError: no trusted keys available """ if not self.trusted: raise PkgbuildGeneratorError diff --git a/src/ahriman/core/triggers/trigger_loader.py b/src/ahriman/core/triggers/trigger_loader.py index 0b0a7e88..82d4405f 100644 --- a/src/ahriman/core/triggers/trigger_loader.py +++ b/src/ahriman/core/triggers/trigger_loader.py @@ -158,13 +158,13 @@ class TriggerLoader(LazyLogging): ModuleType: module loaded from the imported module Raises: - InvalidExtension: in case if module cannot be loaded from specified package + ExtensionError: in case if module cannot be loaded from specified package """ self.logger.info("load module from package %s", package) try: return import_module(package) except ModuleNotFoundError: - raise ExtensionError(f"Module {package} not found") + raise ExtensionError(f"Module {package} not found") from None def load_trigger(self, module_path: str, architecture: str, configuration: Configuration) -> Trigger: """ @@ -179,7 +179,7 @@ class TriggerLoader(LazyLogging): Trigger: loaded trigger based on settings Raises: - InvalidExtension: in case if trigger could not be instantiated + ExtensionError: in case if trigger could not be instantiated """ trigger_type = self.load_trigger_class(module_path) try: @@ -200,7 +200,7 @@ class TriggerLoader(LazyLogging): type[Trigger]: loaded trigger type by module path Raises: - InvalidExtension: in case if module cannot be loaded from the specified module path or is not a trigger + ExtensionError: in case if module cannot be loaded from the specified module path or is not a trigger """ *package_path_parts, class_name = module_path.split(".") package_or_path = ".".join(package_path_parts) diff --git a/src/ahriman/core/upload/upload.py b/src/ahriman/core/upload/upload.py index b2ac61bb..3acf888b 100644 --- a/src/ahriman/core/upload/upload.py +++ b/src/ahriman/core/upload/upload.py @@ -104,13 +104,13 @@ class Upload(LazyLogging): built_packages(list[Package]): list of packages which has just been built Raises: - SyncFailed: in case of any synchronization unmatched exception + SynchronizationError: in case of any synchronization unmatched exception """ try: self.sync(path, built_packages) except Exception: self.logger.exception("remote sync failed") - raise SynchronizationError() + raise SynchronizationError def sync(self, path: Path, built_packages: list[Package]) -> None: """ diff --git a/src/ahriman/core/util.py b/src/ahriman/core/util.py index 0652323b..25a806f0 100644 --- a/src/ahriman/core/util.py +++ b/src/ahriman/core/util.py @@ -160,7 +160,7 @@ def check_user(paths: RepositoryPaths, *, unsafe: bool) -> None: unsafe(bool): if set no user check will be performed before path creation Raises: - UnsafeRun: if root uid differs from current uid and check is enabled + UnsafeRunError: if root uid differs from current uid and check is enabled Examples: Simply run function with arguments:: @@ -345,7 +345,7 @@ def pretty_size(size: float | None, level: int = 0) -> str: str: pretty printable size as string Raises: - InvalidOption: if size is more than 1TiB + OptionError: if size is more than 1TiB """ def str_level() -> str: if level == 0: diff --git a/src/ahriman/models/package.py b/src/ahriman/models/package.py index b89d766b..628f5330 100644 --- a/src/ahriman/models/package.py +++ b/src/ahriman/models/package.py @@ -258,7 +258,7 @@ class Package(LazyLogging): Self: package properties Raises: - InvalidPackageInfo: if there are parsing errors + PackageInfoError: if there are parsing errors """ srcinfo_source = Package._check_output("makepkg", "--printsrcinfo", cwd=path) srcinfo, errors = parse_srcinfo(srcinfo_source) @@ -360,6 +360,9 @@ class Package(LazyLogging): Returns: Generator[Path, None, None]: list of paths of files which belong to the package and distributed together with this tarball. All paths are relative to the ``path`` + + Raises: + PackageInfoError: if there are parsing errors """ srcinfo_source = Package._check_output("makepkg", "--printsrcinfo", cwd=path) srcinfo, errors = parse_srcinfo(srcinfo_source) @@ -396,7 +399,7 @@ class Package(LazyLogging): set[str]: list of package supported architectures Raises: - InvalidPackageInfo: if there are parsing errors + PackageInfoError: if there are parsing errors """ srcinfo_source = Package._check_output("makepkg", "--printsrcinfo", cwd=path) srcinfo, errors = parse_srcinfo(srcinfo_source) @@ -435,7 +438,7 @@ class Package(LazyLogging): str: package version if package is not VCS and current version according to VCS otherwise Raises: - InvalidPackageInfo: if there are parsing errors + PackageInfoError: if there are parsing errors """ if not self.is_vcs: return self.version diff --git a/src/ahriman/models/repository_paths.py b/src/ahriman/models/repository_paths.py index 42ac1f06..20282fc6 100644 --- a/src/ahriman/models/repository_paths.py +++ b/src/ahriman/models/repository_paths.py @@ -166,7 +166,7 @@ class RepositoryPaths: path(Path): path to be chown Raises: - InvalidPath: if path does not belong to root + PathError: if path does not belong to root """ def set_owner(current: Path) -> None: uid, gid = self.owner(current) diff --git a/src/ahriman/models/result.py b/src/ahriman/models/result.py index 75cc0034..ca328013 100644 --- a/src/ahriman/models/result.py +++ b/src/ahriman/models/result.py @@ -104,7 +104,7 @@ class Result: Result: updated instance Raises: - SuccessFailed: if there is previously failed package which is masked as success + UnprocessedPackageStatusError: if there is previously failed package which is masked as success """ for base, package in other._failed.items(): if base in self._success: diff --git a/src/ahriman/web/middlewares/exception_handler.py b/src/ahriman/web/middlewares/exception_handler.py index be87677a..9e05669d 100644 --- a/src/ahriman/web/middlewares/exception_handler.py +++ b/src/ahriman/web/middlewares/exception_handler.py @@ -52,6 +52,9 @@ def exception_handler(logger: logging.Logger) -> MiddlewareType: Returns: MiddlewareType: built middleware + + Raises: + HTTPNoContent: OPTIONS method response """ @middleware async def handle(request: Request, handler: HandlerType) -> StreamResponse: diff --git a/src/ahriman/web/views/base.py b/src/ahriman/web/views/base.py index 44cf2747..6fd89913 100644 --- a/src/ahriman/web/views/base.py +++ b/src/ahriman/web/views/base.py @@ -121,7 +121,7 @@ class BaseView(View, CorsViewMixin): if not value: raise KeyError(key) except Exception: - raise KeyError(f"Key {key} is missing or empty") + raise KeyError(f"Key {key} is missing or empty") from None return value async def data_as_json(self, list_keys: list[str]) -> dict[str, Any]: diff --git a/src/ahriman/web/views/service/pgp.py b/src/ahriman/web/views/service/pgp.py index 6293b81b..9f596bea 100644 --- a/src/ahriman/web/views/service/pgp.py +++ b/src/ahriman/web/views/service/pgp.py @@ -74,7 +74,7 @@ class PGPView(BaseView): try: key = self.service.repository.sign.key_download(server, key) except Exception: - raise HTTPNotFound() + raise HTTPNotFound return json_response({"key": key}) diff --git a/src/ahriman/web/views/service/upload.py b/src/ahriman/web/views/service/upload.py index 0cb79e16..cae5953b 100644 --- a/src/ahriman/web/views/service/upload.py +++ b/src/ahriman/web/views/service/upload.py @@ -113,9 +113,10 @@ class UploadView(BaseView): Raises: HTTPBadRequest: if bad data is supplied HTTPCreated: on success response + HTTPNotFound: method is disabled by configuration """ if not self.configuration.getboolean("web", "enable_archive_upload", fallback=False): - raise HTTPNotFound() + raise HTTPNotFound try: reader = await self.request.multipart() @@ -141,4 +142,4 @@ class UploadView(BaseView): target_location = current_location.parent / filename current_location.rename(target_location) - raise HTTPCreated() + raise HTTPCreated diff --git a/src/ahriman/web/views/status/logs.py b/src/ahriman/web/views/status/logs.py index b7006f64..188fd418 100644 --- a/src/ahriman/web/views/status/logs.py +++ b/src/ahriman/web/views/status/logs.py @@ -65,7 +65,7 @@ class LogsView(BaseView): package_base = self.request.match_info["package"] self.service.logs_remove(package_base, None) - raise HTTPNoContent() + raise HTTPNoContent @aiohttp_apispec.docs( tags=["Packages"], @@ -97,7 +97,7 @@ class LogsView(BaseView): try: _, status = self.service.package_get(package_base) except UnknownPackageError: - raise HTTPNotFound() + raise HTTPNotFound logs = self.service.logs_get(package_base) response = { @@ -143,4 +143,4 @@ class LogsView(BaseView): self.service.logs_update(LogRecordId(package_base, version), created, record) - raise HTTPNoContent() + raise HTTPNoContent diff --git a/src/ahriman/web/views/status/package.py b/src/ahriman/web/views/status/package.py index c4ffe63c..e834e790 100644 --- a/src/ahriman/web/views/status/package.py +++ b/src/ahriman/web/views/status/package.py @@ -66,7 +66,7 @@ class PackageView(BaseView): package_base = self.request.match_info["package"] self.service.package_remove(package_base) - raise HTTPNoContent() + raise HTTPNoContent @aiohttp_apispec.docs( tags=["Packages"], @@ -98,7 +98,7 @@ class PackageView(BaseView): try: package, status = self.service.package_get(package_base) except UnknownPackageError: - raise HTTPNotFound() + raise HTTPNotFound response = [ { @@ -146,4 +146,4 @@ class PackageView(BaseView): except UnknownPackageError: raise HTTPBadRequest(reason=f"Package {package_base} is unknown, but no package body set") - raise HTTPNoContent() + raise HTTPNoContent diff --git a/src/ahriman/web/views/status/packages.py b/src/ahriman/web/views/status/packages.py index c5429fe0..dc26a7de 100644 --- a/src/ahriman/web/views/status/packages.py +++ b/src/ahriman/web/views/status/packages.py @@ -88,4 +88,4 @@ class PackagesView(BaseView): """ self.service.load() - raise HTTPNoContent() + raise HTTPNoContent diff --git a/src/ahriman/web/views/status/status.py b/src/ahriman/web/views/status/status.py index 3f94f90c..2de728a3 100644 --- a/src/ahriman/web/views/status/status.py +++ b/src/ahriman/web/views/status/status.py @@ -104,4 +104,4 @@ class StatusView(BaseView): self.service.status_update(status) - raise HTTPNoContent() + raise HTTPNoContent diff --git a/src/ahriman/web/views/user/login.py b/src/ahriman/web/views/user/login.py index 5f4e49f9..bf78399f 100644 --- a/src/ahriman/web/views/user/login.py +++ b/src/ahriman/web/views/user/login.py @@ -84,7 +84,7 @@ class LoginView(BaseView): await remember(self.request, response, identity) raise response - raise HTTPUnauthorized() + raise HTTPUnauthorized @aiohttp_apispec.docs( tags=["Login"], @@ -114,4 +114,4 @@ class LoginView(BaseView): await remember(self.request, response, identity) raise response - raise HTTPUnauthorized() + raise HTTPUnauthorized diff --git a/src/ahriman/web/views/user/logout.py b/src/ahriman/web/views/user/logout.py index 0b36d158..3db4aaf2 100644 --- a/src/ahriman/web/views/user/logout.py +++ b/src/ahriman/web/views/user/logout.py @@ -57,6 +57,7 @@ class LogoutView(BaseView): Raises: HTTPFound: on success response + HTTPUnauthorized: no authorization cookie available """ try: await check_authorized(self.request)