mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-07-14 22:45:47 +00:00
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
This commit is contained in:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
"""
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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]:
|
||||
|
@ -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})
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -88,4 +88,4 @@ class PackagesView(BaseView):
|
||||
"""
|
||||
self.service.load()
|
||||
|
||||
raise HTTPNoContent()
|
||||
raise HTTPNoContent
|
||||
|
@ -104,4 +104,4 @@ class StatusView(BaseView):
|
||||
|
||||
self.service.status_update(status)
|
||||
|
||||
raise HTTPNoContent()
|
||||
raise HTTPNoContent
|
||||
|
@ -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
|
||||
|
@ -57,6 +57,7 @@ class LogoutView(BaseView):
|
||||
|
||||
Raises:
|
||||
HTTPFound: on success response
|
||||
HTTPUnauthorized: no authorization cookie available
|
||||
"""
|
||||
try:
|
||||
await check_authorized(self.request)
|
||||
|
Reference in New Issue
Block a user