Skip to content

refactor: move ExitException and exit codes out of cli package - #2602

Merged
maxandersen merged 1 commit into
jbangdev:mainfrom
maxandersen:refactor/exit-exception-package
Jul 13, 2026
Merged

refactor: move ExitException and exit codes out of cli package#2602
maxandersen merged 1 commit into
jbangdev:mainfrom
maxandersen:refactor/exit-exception-package

Conversation

@maxandersen

@maxandersen maxandersen commented Jul 12, 2026

Copy link
Copy Markdown
Collaborator

What

Moves ExitException from dev.jbang.cli to dev.jbang with exit code constants and factory methods on the class itself.

Why

ExitException is jbang's universal error type — used in 30+ files across catalog, dependencies, source, util, net, and spi packages. It just happened to live in dev.jbang.cli because that's where it started. This created the only reverse dependency (core → cli) blocking a clean jbang-core library split (see #1128).

Changes

  • dev.jbang.ExitException — moved from dev.jbang.cli, now contains both exit code constants and factory methods
  • dev.jbang.cli.ExitException — deleted (no compat shim needed)
  • BaseCommand — retains deprecated delegate constants for backward compat
  • 55 files — updated imports (mechanical, no logic changes)
  • All 840 tests pass (1 pre-existing unrelated failure)

Constants on ExitException

ExitException.EXIT_OK              // 0
ExitException.EXIT_GENERIC_ERROR   // 1
ExitException.EXIT_INVALID_INPUT   // 2
ExitException.EXIT_UNEXPECTED_STATE // 3
ExitException.EXIT_INTERNAL_ERROR  // 4
ExitException.EXIT_EXECUTE         // 255

Factory methods

throw ExitException.invalidInput("bad input");
throw ExitException.invalidInput("bad input", cause);
throw ExitException.unexpectedState("missing file");
throw ExitException.unexpectedState("missing file", cause);
throw ExitException.genericError("failed");
throw ExitException.genericError("failed", cause);
throw ExitException.genericError(cause);
throw ExitException.internalError("should not happen");
throw ExitException.internalError("should not happen", cause);

What this enables

With this change, the non-cli packages have zero imports from dev.jbang.cli. A future Gradle multi-project split into jbang-core (105 files, 18K LoC) and jbang-cli (38 files, 8K LoC) would be a pure build config change — no source moves needed.

Options for #1128 going forward

Approach Effort When
This PR — fix package layering Done Now
Gradle multi-project split Medium When there's an actual consumer of jbang-core (plugin SDK, IDE integration)
java-library + api vs implementation Low Lightweight alternative to enforce API boundaries without subprojects

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ai-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 380834b3-e520-4df6-a82c-88254a9dee73

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Move ExitException from dev.jbang.cli to dev.jbang with exit code
constants and factory methods directly on the class:

  throw ExitException.invalidInput("bad input");
  throw ExitException.unexpectedState("missing file", cause);
  throw ExitException.genericError(cause);
  throw ExitException.internalError("should not happen");

Constants (EXIT_OK, EXIT_GENERIC_ERROR, etc.) live on ExitException.
BaseCommand retains deprecated delegate constants for backward compat.

This breaks the only reverse dependency (core -> cli), making a future
jbang-core library split straightforward.

All 840 tests pass (1 pre-existing unrelated failure).
@maxandersen
maxandersen force-pushed the refactor/exit-exception-package branch from 29a5b08 to c88852c Compare July 12, 2026 11:49
@maxandersen
maxandersen requested a review from quintesse July 12, 2026 12:36
@maxandersen

Copy link
Copy Markdown
Collaborator Author

wdyt @quintesse, right direction?

we could go add archunit to ensure this cross dep dont happen again.

@maxandersen
maxandersen force-pushed the refactor/exit-exception-package branch from b8b664d to c88852c Compare July 12, 2026 12:49
@quintesse

Copy link
Copy Markdown
Contributor

LGTM! 👍

@maxandersen

Copy link
Copy Markdown
Collaborator Author

Click the review approve button please. Then I don't have to break GitHub ui rules all the time :)

@quintesse quintesse left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@quintesse

Copy link
Copy Markdown
Contributor

Click the review approve button please. Then I don't have to break GitHub ui rules all the time :)

I was on my phone and didn't want to go through 3 levels of pages and dialogs to just give a 👍 😉

@maxandersen
maxandersen merged commit b3d1b30 into jbangdev:main Jul 13, 2026
56 checks passed
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.

2 participants