Skip to content

[OC-818] Fix silent failures in module install - #417

Open
cvaske wants to merge 2 commits into
masterfrom
cvaske/cv-OC-818-partial-module-install
Open

[OC-818] Fix silent failures in module install#417
cvaske wants to merge 2 commits into
masterfrom
cvaske/cv-OC-818-partial-module-install

Conversation

@cvaske

@cvaske cvaske commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

install_module() swallowed KeyboardInterrupt/SystemExit/ KillInstallException and returned normally after a failed or interrupted install, so callers had no way to detect the failure. install_modules() didn't check per-module failures either, and oc.py's top-level handler printed errors but never set a non-zero exit code.

  • admin_util.py: install_module() now always re-raises after cleanup instead of swallowing the exception.
  • cravat_admin.py: install_modules()/update_modules() catch per-module failures, keep going for independent modules, let a real interrupt abort the whole batch, and exit(1) with a summary if anything failed.
  • oc.py: main() now exits non-zero on any uncaught exception, and exits 130 on KeyboardInterrupt, instead of printing "ERROR" and returning 0.

cvaske added 2 commits August 6, 2026 20:52
install_module() swallowed KeyboardInterrupt/SystemExit/
KillInstallException and returned normally after a failed or
interrupted install, so callers had no way to detect the failure.
install_modules() didn't check per-module failures either, and
oc.py's top-level handler printed errors but never set a non-zero
exit code.

- admin_util.py: install_module() now always re-raises after cleanup
  instead of swallowing the exception.
- cravat_admin.py: install_modules()/update_modules() catch
  per-module failures, keep going for independent modules, let a
  real interrupt abort the whole batch, and exit(1) with a summary
  if anything failed.
- oc.py: main() now exits non-zero on any uncaught exception, and
  exits 130 on KeyboardInterrupt, instead of printing "ERROR" and
  returning 0.
install_modules() resolved requested names via au.search_remote()
regex matching but never checked whether every requested name/pattern
actually matched something. A typo'd or nonexistent module name was
silently dropped: the command printed nothing about it, installed
whatever else matched (or nothing at all), and exited 0.

- exceptions.py: add ModuleNotFound, raised with the list of
  unmatched names/patterns.
- cravat_admin.py: install_modules() now diffs args.modules against
  matching_names (and, for --include-private, against the names
  actually found privately) and raises ModuleNotFound before
  resolving dependencies or attempting any install if anything is
  unmatched — consistent with the function's existing fail-fast
  validation for --version/--include-private conflicts.
- cravat_admin.py: update_modules()'s per-module retry loop now also
  catches ModuleNotFound (previously only SystemExit) so one bad
  module name during a batch update is reported and skipped rather
  than aborting the whole update.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant