mirror of
https://github.com/kiviktnm/decman.git
synced 2026-09-19 12:08:28 +00:00
Improve error reporting
This commit is contained in:
+35
-28
@@ -23,33 +23,35 @@ def sh(sh_cmd: str,
|
||||
env = os.environ.copy()
|
||||
for var, val in env_overrides.items():
|
||||
env[var] = val
|
||||
try:
|
||||
|
||||
if user is None:
|
||||
if user is None:
|
||||
try:
|
||||
subprocess.run(sh_cmd, shell=True, check=True, env=env)
|
||||
else:
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user defined shell command '{sh_cmd}' failed."
|
||||
) from e
|
||||
else:
|
||||
try:
|
||||
uid = pwd.getpwnam(user).pw_uid
|
||||
gid = pwd.getpwnam(user).pw_gid
|
||||
except KeyError as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user defined shell command failed because the user {user} doesn't exist."
|
||||
) from e
|
||||
|
||||
with subprocess.Popen(sh_cmd,
|
||||
shell=True,
|
||||
group=gid,
|
||||
user=uid,
|
||||
env=env) as process:
|
||||
if process.wait() != 0:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user shell command '{sh_cmd}' as {user} failed."
|
||||
)
|
||||
except (subprocess.CalledProcessError, KeyError) as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user shell command '{sh_cmd}' failed.") from e
|
||||
with subprocess.Popen(sh_cmd, shell=True, group=gid, user=uid,
|
||||
env=env) as process:
|
||||
if process.wait() != 0:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user shell command '{sh_cmd}' as {user} failed.")
|
||||
|
||||
|
||||
def cmd(command: list[str],
|
||||
def prg(command: list[str],
|
||||
user: typing.Optional[str] = None,
|
||||
env_overrides: typing.Optional[dict[str, str]] = None):
|
||||
"""
|
||||
Shortcut for running a command.
|
||||
Shortcut for running a program.
|
||||
"""
|
||||
if env_overrides is None:
|
||||
env_overrides = {}
|
||||
@@ -58,21 +60,26 @@ def cmd(command: list[str],
|
||||
for var, val in env_overrides.items():
|
||||
env[var] = val
|
||||
|
||||
try:
|
||||
if user is None:
|
||||
if user is None:
|
||||
try:
|
||||
subprocess.run(command, check=True, env=env)
|
||||
else:
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user defined program '{command}' failed.") from e
|
||||
else:
|
||||
try:
|
||||
uid = pwd.getpwnam(user).pw_uid
|
||||
gid = pwd.getpwnam(user).pw_gid
|
||||
except KeyError as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user defined program failed because the user {user} doesn't exist."
|
||||
) from e
|
||||
|
||||
with subprocess.Popen(command, group=gid, user=uid,
|
||||
env=env) as process:
|
||||
if process.wait() != 0:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user command '{command}' as {user} failed.")
|
||||
except (subprocess.CalledProcessError, KeyError) as e:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user command '{command}' failed.") from e
|
||||
with subprocess.Popen(command, group=gid, user=uid,
|
||||
env=env) as process:
|
||||
if process.wait() != 0:
|
||||
raise decman.error.UserFacingError(
|
||||
f"Running user program '{command}' as {user} failed.")
|
||||
|
||||
|
||||
class File:
|
||||
|
||||
+30
-15
@@ -182,7 +182,8 @@ class Store:
|
||||
with open(path, "wt", encoding="utf-8") as file:
|
||||
json.dump(d, file)
|
||||
except OSError as e:
|
||||
raise err.UserFacingError("Failed to save store.") from e
|
||||
print_error(f"{e}")
|
||||
raise err.UserFacingError("Failed to save decman store.") from e
|
||||
|
||||
@staticmethod
|
||||
def restore() -> "Store":
|
||||
@@ -220,9 +221,13 @@ class Store:
|
||||
|
||||
return store
|
||||
except json.JSONDecodeError as e:
|
||||
raise err.UserFacingError("Failed to parse state json.") from e
|
||||
print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to parse decman store json.") from e
|
||||
except OSError as e:
|
||||
raise err.UserFacingError("Failed to read saved store.") from e
|
||||
print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to read saved decman store.") from e
|
||||
|
||||
|
||||
class Source:
|
||||
@@ -302,6 +307,7 @@ class Source:
|
||||
file.copy_to(target, variables)
|
||||
print_debug(f"Installing file to {target}.")
|
||||
except OSError as e:
|
||||
print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
f"Failed to install file to {target}.") from e
|
||||
|
||||
@@ -312,6 +318,7 @@ class Source:
|
||||
print_debug(f"Installing directory to {target}.")
|
||||
directory.copy_to(target, variables)
|
||||
except OSError as e:
|
||||
print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
f"Failed to install directory to {target}.") from e
|
||||
|
||||
@@ -543,7 +550,7 @@ class Pacman:
|
||||
for line in output]
|
||||
except IndexError as error:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to get foreign packages from pacman output. Output: {output}"
|
||||
f"Failed to parse foreign packages from pacman output. Output: {output}"
|
||||
) from error
|
||||
|
||||
def install(self, packages: list[str]):
|
||||
@@ -553,7 +560,8 @@ class Pacman:
|
||||
try:
|
||||
subprocess.run(conf.commands.install_pkgs(packages), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError("Failed to install packages.") from error
|
||||
raise err.UserFacingError(
|
||||
"Failed to install packages using pacman.") from error
|
||||
|
||||
def install_dependencies(self, deps: list[str]):
|
||||
"""
|
||||
@@ -563,7 +571,8 @@ class Pacman:
|
||||
subprocess.run(conf.commands.install_deps(deps), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError(
|
||||
"Failed to install dependency packages.") from error
|
||||
"Failed to install packages as dependencies using pacman."
|
||||
) from error
|
||||
|
||||
def install_files(self, files: list[str], as_explicit: list[str]):
|
||||
"""
|
||||
@@ -577,8 +586,11 @@ class Pacman:
|
||||
check=True,
|
||||
capture_output=conf.suppress_command_output)
|
||||
except subprocess.CalledProcessError as error:
|
||||
if conf.suppress_command_output:
|
||||
print_error("Output:")
|
||||
print_continuation(error.output)
|
||||
raise err.UserFacingError(
|
||||
"Failed to install foreign packages.") from error
|
||||
"Failed to install package files using pacman.") from error
|
||||
|
||||
def upgrade(self):
|
||||
"""
|
||||
@@ -587,7 +599,8 @@ class Pacman:
|
||||
try:
|
||||
subprocess.run(conf.commands.upgrade(), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError("Failed to update packages.") from error
|
||||
raise err.UserFacingError(
|
||||
"Failed to upgrade packages using pacman.") from error
|
||||
|
||||
def remove(self, packages: list[str]):
|
||||
"""
|
||||
@@ -596,7 +609,8 @@ class Pacman:
|
||||
try:
|
||||
subprocess.run(conf.commands.remove(packages), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError("Failed to remove packages.") from error
|
||||
raise err.UserFacingError(
|
||||
"Failed to remove packages using pacman.") from error
|
||||
|
||||
|
||||
class Systemd:
|
||||
@@ -615,7 +629,7 @@ class Systemd:
|
||||
subprocess.run(conf.commands.enable_units(units), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError(
|
||||
"Failed to enable systemd units.") from error
|
||||
f"Failed to enable systemd units: {units}") from error
|
||||
self.state.enabled_systemd_units += units
|
||||
|
||||
def disable_units(self, units: list[str]):
|
||||
@@ -626,7 +640,7 @@ class Systemd:
|
||||
subprocess.run(conf.commands.disable_units(units), check=True)
|
||||
except subprocess.CalledProcessError as error:
|
||||
raise err.UserFacingError(
|
||||
"Failed to disable systemd units.") from error
|
||||
f"Failed to disable systemd units: {units}") from error
|
||||
for unit in units:
|
||||
try:
|
||||
self.state.enabled_systemd_units.remove(unit)
|
||||
@@ -646,10 +660,10 @@ class Systemd:
|
||||
user=uid) as process:
|
||||
if process.wait() != 0:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to enable systemd units for {user}.")
|
||||
f"Failed to enable systemd units: {units} for {user}.")
|
||||
except KeyError as error:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to enable systemd units because user '{user}' doesn't exist."
|
||||
f"Failed to enable systemd units because user {user} doesn't exist."
|
||||
) from error
|
||||
for unit in units:
|
||||
self.state.enabled_user_systemd_units.append((user, unit))
|
||||
@@ -667,10 +681,11 @@ class Systemd:
|
||||
user=uid) as process:
|
||||
if process.wait() != 0:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to disable systemd units for {user}.")
|
||||
f"Failed to disable systemd units: {units} for {user}."
|
||||
)
|
||||
except KeyError as error:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to disable systemd units because user '{user}' doesn't exist."
|
||||
f"Failed to disable systemd units because user {user} doesn't exist."
|
||||
) from error
|
||||
|
||||
for unit in units:
|
||||
|
||||
+21
-7
@@ -324,8 +324,10 @@ class ExtendedPackageSearch:
|
||||
|
||||
l.print_debug("Request completed.")
|
||||
except (requests.RequestException, KeyError) as e:
|
||||
l.print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to fetch package information from AUR RPC.") from e
|
||||
f"Failed to fetch package information for {packages} from AUR RPC."
|
||||
) from e
|
||||
|
||||
def get_package_info(self, package: str) -> typing.Optional[PackageInfo]:
|
||||
"""
|
||||
@@ -379,8 +381,10 @@ class ExtendedPackageSearch:
|
||||
|
||||
return info
|
||||
except (requests.RequestException, KeyError) as e:
|
||||
l.print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to fetch package information from AUR RPC.") from e
|
||||
f"Failed to fetch package information for {package} from AUR RPC."
|
||||
) from e
|
||||
|
||||
def find_provider(
|
||||
self, stripped_dependency: str) -> typing.Optional[PackageInfo]:
|
||||
@@ -452,8 +456,10 @@ class ExtendedPackageSearch:
|
||||
|
||||
return self._choose_provider(stripped_dependency, results, "AUR")
|
||||
except (requests.RequestException, KeyError) as e:
|
||||
l.print_error(f"{e}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to fetch package information from AUR RPC.") from e
|
||||
f"Failed to search for {stripped_dependency} from AUR RPC."
|
||||
) from e
|
||||
|
||||
def _choose_provider(self, dep: str, possible_providers: list[str],
|
||||
where: str) -> typing.Optional[PackageInfo]:
|
||||
@@ -569,7 +575,9 @@ class ForeignPackageManager:
|
||||
|
||||
info = self._search.get_package_info(pkg)
|
||||
if info is None:
|
||||
raise err.UserFacingError(f"Failed to find package: {pkg}.")
|
||||
raise err.UserFacingError(
|
||||
f"Failed to find '{pkg}' from AUR or user provided packages."
|
||||
)
|
||||
|
||||
if self.should_upgrade_package(pkg, ver, info.version,
|
||||
upgrade_devel):
|
||||
@@ -650,6 +658,7 @@ class ForeignPackageManager:
|
||||
|
||||
builder.build_packages(pkgbase, packages, force)
|
||||
except (subprocess.CalledProcessError, OSError) as e:
|
||||
l.print_error(f"{e}")
|
||||
raise err.UserFacingError("Failed to build packages.") from e
|
||||
|
||||
packages_to_install = list(resolved_dependencies.foreign_pkgs)
|
||||
@@ -792,7 +801,9 @@ class ForeignPackageManager:
|
||||
)
|
||||
return should_upgrade
|
||||
except (ValueError, subprocess.CalledProcessError) as error:
|
||||
raise err.UserFacingError("Failed to compare versions.") from error
|
||||
l.print_error(f"{error}")
|
||||
raise err.UserFacingError(
|
||||
"Failed to compare versions using vercmp.") from error
|
||||
|
||||
|
||||
class PackageBuilder:
|
||||
@@ -1031,7 +1042,7 @@ class PackageBuilder:
|
||||
for foreign_pkg in chroot_foreign_pkgs:
|
||||
entry = self._store.get_package(foreign_pkg)
|
||||
assert entry is not None, "Build order determines that the dependencies are built \
|
||||
before and thus are found in the cache."
|
||||
before and thus are found in the cache."
|
||||
|
||||
_, file = entry
|
||||
|
||||
@@ -1058,7 +1069,7 @@ class PackageBuilder:
|
||||
|
||||
if len(matches) != 1:
|
||||
raise err.UserFacingError(
|
||||
f"Failed to build package '{pkgname}', because the pkg file cannot be determined."
|
||||
f"Failed to build package '{pkgname}', because the pkg file cannot be determined. Possible files are: {matches}"
|
||||
)
|
||||
|
||||
return matches[0]
|
||||
@@ -1100,6 +1111,9 @@ class PackageBuilder:
|
||||
raise err.UserFacingError("Building aborted.")
|
||||
|
||||
except subprocess.CalledProcessError as error:
|
||||
if conf.suppress_command_output:
|
||||
l.print_error("Output:")
|
||||
l.print_continuation(error.output)
|
||||
raise err.UserFacingError(
|
||||
f"Failed to clone and review PKGBUILD from {git_url}"
|
||||
) from error
|
||||
|
||||
Reference in New Issue
Block a user