feat: standardize exit codes across all CLI commands#882
Merged
Conversation
Add semantic exit codes to every CliError subclass so scripts, CI pipelines, and AI agents can react to failure categories without parsing stderr. Exit codes are grouped into decades inspired by HTTP status semantics: - 1x: Auth & identity (401/403 family) - 2x: Input & config (400/404/422 family) - 3x: API & network (502/504 family) - 4x: Feature/billing (402/451 family) - 5x: Operations (upgrade, OAuth) - 6x: Command-specific All codes stay below 128 to avoid collision with Unix signal exits. Closes #392
Contributor
|
Contributor
Codecov Results 📊✅ 6317 passed | Total: 6317 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
All tests are passing successfully. ❌ Patch coverage is 72.92%. Project has 13142 uncovered lines. Files with missing lines (3)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 75.97% 75.89% -0.08%
==========================================
Files 294 294 —
Lines 54402 54503 +101
Branches 0 0 —
==========================================
+ Hits 41329 41361 +32
- Misses 13073 13142 +69
- Partials 0 0 —Generated by Codecov Action |
sentry api wraps API errors in OutputError (renders response to stdout), so the exit code is OUTPUT_ERROR (60), not API (30). Trace view gets 200 with empty array for non-existent traces, so it throws ValidationError (21), not ApiError (30).
…utionError - CliError base constructor now uses EXIT.GENERAL instead of hardcoded 1 - trace/view: 'no trace found' throws ResolutionError (exit 23) instead of ValidationError (exit 21) — the user provided a valid ID that couldn't be resolved, not malformed input - log/view: same fix for throwNotFoundError — 'log not found' is a resolution failure, not a validation failure - exit-codes.md: document sentry api OutputError behavior, fix Python example to use range checks - agent-guidance.md: add 50-69 ranges to exit code table
…slug
- log/view: restructure multi-log ResolutionError to keep headline
single-line ('2 log(s) not found in org/project') and move IDs to
suggestions list, avoiding awkward period placement
- trace/view: include project slug in ResolutionError hint so the
suggested command doesn't immediately fail with ContextError
Add wizard sub-codes in the 60s range (62=deps, 63=codemod, 64=verify) so scripts can distinguish wizard failure categories. The remote workflow's internal codes (20, 30, 40/41, 50) are mapped to EXIT.* constants in mapWorkflowExitCode() before reaching process exit. Platform-not-detected (workflow code 20) maps to EXIT.CONFIG (20) since it's fundamentally a project configuration issue.
Contributor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 78c6803. Configure here.
- trace/view: guard project with fallback placeholder in hint to avoid interpolating 'undefined' as a literal string - wizard-runner: use EXIT_PLATFORM_NOT_DETECTED, EXIT_DEPENDENCY_INSTALL_FAILED, EXIT_VERIFICATION_FAILED constants instead of magic numbers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
Adds semantic exit codes to every
CliErrorsubclass so scripts, CI pipelines, and AI agents can react to failure categories without parsing stderr.EXITconstant object tosrc/lib/errors.tswith 18 semantic codestrace/viewandlog/viewto throwResolutionError(exit 23) instead ofValidationError(exit 21) for "not found" cases — aligning with the error hierarchy guidelines/exit-codes/with scripting examplessentry apiOutputError convention (exit 60 for API errors rendered to stdout)Exit Code Ranges
Error Classification Fix
This PR also fixes two pre-existing error classification issues that would have been cemented as permanent API contracts by the new exit codes:
trace view: "No trace found" now throwsResolutionError(exit 23) instead ofValidationError(exit 21). A valid hex ID that doesn't match any trace is a resolution failure, not a validation failure.log view: Same fix —throwNotFoundErrornow throwsResolutionErrorfor logs that don't exist.Backward Compatibility
Purely additive — exit code 1 becomes more specific (10, 20, 21, etc.). Scripts that check
!= 0are unaffected.Closes #392