Skip to content

feat(error): add structured exit codes for scriptable error handling#428

Merged
jpoehnelt merged 3 commits intogoogleworkspace:mainfrom
abhiram304:feat/structured-exit-codes
Mar 12, 2026
Merged

feat(error): add structured exit codes for scriptable error handling#428
jpoehnelt merged 3 commits intogoogleworkspace:mainfrom
abhiram304:feat/structured-exit-codes

Conversation

@abhiram304
Copy link
Contributor

Summary

  • Replaces the hardcoded std::process::exit(1) with a type-specific exit code derived from the GwsError variant
  • Adds GwsError::exit_code() mapping each error kind to a stable, documented code
  • Documents exit codes in gws --help output and in the README under a new Exit Codes section

Exit code table

Code Meaning GwsError variant
0 Success
1 API error — Google returned a 4xx/5xx Api
2 Auth error — credentials missing or invalid Auth
3 Validation error — bad args, unknown service Validation
4 Discovery error — could not fetch API schema Discovery
5 Internal error — unexpected failure Other

Usage in scripts

gws drive files list --params '{"fileId": "bad-id"}'
case $? in
  1) echo "API error — check your params or permissions" ;;
  2) echo "Auth error — run: gws auth login" ;;
  3) echo "Bad arguments" ;;
  4) echo "Network error — check connectivity" ;;
esac

Test plan

  • cargo test — 556 passed, 0 failed
  • cargo clippy -- -D warnings — clean
  • 6 new unit tests: one per variant + regression guard asserting all codes are distinct
  • Changeset included (minor bump)

🤖 Generated with Claude Code

Replace the hardcoded `std::process::exit(1)` with a type-specific exit
code derived from the GwsError variant:

  0 — success
  1 — API error      (GwsError::Api)
  2 — auth error     (GwsError::Auth)
  3 — validation     (GwsError::Validation)
  4 — discovery      (GwsError::Discovery)
  5 — internal       (GwsError::Other)

This allows shell scripts to branch on failure type without parsing the
JSON error output:

  gws drive files list ...
  case $? in
    1) echo "API error — check your params" ;;
    2) echo "Auth error — run: gws auth login" ;;
    3) echo "Bad arguments" ;;
  esac

Changes:
- Add GwsError::exit_code() mapping variants to codes
- Update main() to call std::process::exit(err.exit_code())
- Document exit codes in gws --help (print_usage)
- Document exit codes in README under new Exit Codes section
- Add 6 unit tests including a regression guard asserting all codes are distinct
@abhiram304 abhiram304 requested a review from jpoehnelt as a code owner March 12, 2026 07:27
@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: be31c31

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@googleworkspace/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@googleworkspace-bot googleworkspace-bot added area: docs area: core Core CLI parsing, commands, error handling, utilities labels Mar 12, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the scriptability and robustness of the gws command-line tool by introducing structured exit codes. Instead of a generic failure code, the application now exits with distinct codes corresponding to different error types, such as API errors, authentication issues, or validation failures. This allows external scripts to reliably interpret the nature of an error without needing to parse output messages, making automation more precise and less prone to breakage.

Highlights

  • Structured Exit Codes: Replaced the generic std::process::exit(1) with specific, type-based exit codes derived from GwsError variants, enabling more granular error handling in scripts.
  • Error Handling Logic: Implemented a new GwsError::exit_code() method that maps each error variant to a unique, stable integer exit code.
  • Documentation: Added comprehensive documentation for the new exit codes in the gws --help output and a dedicated 'Exit Codes' section in the README.md.
  • Testing: Introduced six new unit tests to verify the correct mapping of GwsError variants to their respective exit codes and to ensure all assigned codes are distinct.
Changelog
  • .changeset/structured-exit-codes.md
    • Added a new changeset file documenting the introduction of structured exit codes and their meanings.
  • README.md
    • Updated the table of contents to include a new 'Exit Codes' section.
    • Appended a new 'Exit Codes' section detailing the structured exit codes, their meanings, and example causes, along with usage examples.
  • src/error.rs
    • Implemented the exit_code method for the GwsError enum, mapping each error variant to a specific integer.
    • Added unit tests for each GwsError variant to confirm correct exit code assignment.
    • Included a regression guard unit test to ensure all exit codes remain distinct.
  • src/main.rs
    • Modified the main error handling logic to use the err.exit_code() method for process termination.
    • Updated the print_usage function to display a new 'EXIT CODES' section, listing all defined exit codes and their descriptions.
Activity
  • The pull request includes a new changeset file, indicating a minor version bump.
  • Six new unit tests were added to cover the new exit code functionality.
  • All existing cargo test and cargo clippy checks passed successfully.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Generative AI Prohibited Use Policy, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@google-cla
Copy link

google-cla bot commented Mar 12, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces structured exit codes, which is a great feature for scriptability. The implementation is straightforward and well-tested. I've added a few suggestions to src/error.rs to improve maintainability by replacing magic numbers with constants, which is important for a public contract like exit codes. The documentation changes in the README and help output are clear and helpful.

Add EXIT_CODE_API/AUTH/VALIDATION/DISCOVERY/OTHER associated constants
on GwsError so callers and tests reference symbolic names rather than
bare integers. Update exit_code() match arms and all tests accordingly.
The distinctness test now validates the constants array directly.

Addresses code-review feedback requesting named constants.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces structured exit codes, which is a great improvement for scriptability. The implementation is solid, with new constants for exit codes, an exit_code() method on GwsError, and accompanying tests. The documentation has also been updated accordingly. I have one suggestion to improve maintainability by reducing documentation duplication for the exit codes in the help text.

src/main.rs Outdated
Comment on lines +463 to +469
println!("EXIT CODES:");
println!(" 0 Success");
println!(" 1 API error — Google returned an error response");
println!(" 2 Auth error — credentials missing or invalid");
println!(" 3 Validation — bad arguments or input");
println!(" 4 Discovery — could not fetch API schema");
println!(" 5 Internal — unexpected failure");
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The exit code documentation is hardcoded here using println!. This information is duplicated in several other places, including the doc comment in src/error.rs, README.md, and the changeset file. This duplication makes maintenance difficult and increases the risk of documentation becoming inconsistent with the implementation.

To improve maintainability and ensure a single source of truth for the help output, this information should be centralized. A good place would be src/error.rs alongside the exit code constants.

For example, you could add this constant to src/error.rs:

pub const EXIT_CODE_DOCUMENTATION: &[(i32, &str)] = &[
    (0, "Success"),
    (crate::error::GwsError::EXIT_CODE_API, "API error  — Google returned an error response"),
    (crate::error::GwsError::EXIT_CODE_AUTH, "Auth error — credentials missing or invalid"),
    (crate::error::GwsError::EXIT_CODE_VALIDATION, "Validation — bad arguments or input"),
    (crate::error::GwsError::EXIT_CODE_DISCOVERY, "Discovery  — could not fetch API schema"),
    (crate::error::GwsError::EXIT_CODE_OTHER, "Internal   — unexpected failure"),
];

And then replace this block of println! statements with a loop that uses the constant, ensuring the help text is always in sync with the code.

Suggested change
println!("EXIT CODES:");
println!(" 0 Success");
println!(" 1 API error — Google returned an error response");
println!(" 2 Auth error — credentials missing or invalid");
println!(" 3 Validation — bad arguments or input");
println!(" 4 Discovery — could not fetch API schema");
println!(" 5 Internal — unexpected failure");
println!("EXIT CODES:");
for (code, description) in crate::error::EXIT_CODE_DOCUMENTATION {
println!(" {:<5}{}", code, description);
}

…TATION

Add a module-level EXIT_CODE_DOCUMENTATION constant — a static slice of
(code, description) pairs built from the EXIT_CODE_* constants. Replace
the hardcoded println! block in print_usage() with a loop over this slice
so the help output is always in sync with the defined constants and cannot
drift out of date.

Addresses code-review feedback requesting a single source of truth.
@googleworkspace-bot
Copy link
Collaborator

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces structured exit codes to the gws CLI tool, replacing the generic exit code 1 with specific codes for different error types (API, Auth, Validation, Discovery, and Internal errors). The changes include defining constant exit codes and a mapping function within the GwsError enum, updating the main application to use these new codes, and adding comprehensive documentation in the README.md, a new changeset file, and the gws --help output. Unit tests were also added to verify the correctness and distinctness of these exit codes.

@jpoehnelt jpoehnelt merged commit 247e27a into googleworkspace:main Mar 12, 2026
28 of 30 checks passed
@codecov
Copy link

codecov bot commented Mar 12, 2026

Codecov Report

❌ Patch coverage is 88.00000% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.47%. Comparing base (7e22a3d) to head (be31c31).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
src/main.rs 0.00% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #428      +/-   ##
==========================================
+ Coverage   64.40%   64.47%   +0.06%     
==========================================
  Files          38       38              
  Lines       15584    15633      +49     
==========================================
+ Hits        10037    10079      +42     
- Misses       5547     5554       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: core Core CLI parsing, commands, error handling, utilities area: docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants