Skip to content

fix: ensure CLI exits with non-zero code on errors#694

Open
BigBalli wants to merge 2 commits intoapache:masterfrom
BigBalli:fix/exit-code-540
Open

fix: ensure CLI exits with non-zero code on errors#694
BigBalli wants to merge 2 commits intoapache:masterfrom
BigBalli:fix/exit-code-540

Conversation

@BigBalli
Copy link
Copy Markdown

@BigBalli BigBalli commented Apr 2, 2026

Summary

Fixes the CLI silently exiting with code 0 when errors occur as unhandled rejections.

Changes:

  • src/cli.js: Add unhandledRejection handler so rejected promises that bypass the bin/cordova .catch() are caught and exit with code 1 (mirrors the existing uncaughtException handler)
  • src/cli.js: Return result from printHelp() so the promise chain resolves with the help text
  • bin/cordova: No changes to the existing .catch()process.exitCode is the correct mechanism for graceful exit

Test plan

  • Run cordova build with invalid platform — verify non-zero exit code
  • Trigger an unhandled rejection path — verify non-zero exit code
  • Run cordova help — verify output is printed and process exits cleanly

Closes apache#540. Three fixes:
1. bin/cordova: call process.exit() explicitly after setting exitCode
2. src/cli.js: add unhandledRejection handler to catch unhandled promise rejections
3. src/cli.js: make printHelp() return its result so the promise chain works

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@breautek
Copy link
Copy Markdown
Contributor

breautek commented Apr 3, 2026

bin/cordova: The .catch() handler sets process.exitCode but never calls process.exit(), so Node exits with 0 before the exit code takes effect. Added an explicit process.exit(exitCode) call.

This doesn't really make sense. process.exit is a forceful synchronous exit. It will not wait for pending asynchronous tasks including stdio writes. The more "proper" way to exit node is to set exitCode and let the nodejs process exit gracefully, including any open streams and waiting for open async handlers to run their completion, and a graceful exit will use process.exitCode as it's exit code.

In most situations, it is not actually necessary to call process.exit() explicitly. The Node.js process will exit on its own if there is no additional work pending in the event loop. The process.exitCode property can be set to tell the process which exit code to use when the process exits gracefully.

So introducing process.exit here makes me worry about closing the process prematurely.

@BigBalli
Copy link
Copy Markdown
Author

BigBalli commented Apr 3, 2026

Oh right, that makes sense...

process.exitCode is sufficient — Node will use it on graceful exit.
process.exit() is a forceful synchronous exit that can truncate
pending stdio writes and skip async cleanup.
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 73.33%. Comparing base (4014430) to head (718039e).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #694      +/-   ##
==========================================
+ Coverage   72.90%   73.33%   +0.43%     
==========================================
  Files           3        3              
  Lines         620      630      +10     
==========================================
+ Hits          452      462      +10     
  Misses        168      168              

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@breautek breautek left a comment

Choose a reason for hiding this comment

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

Thanks for taking the time to respond to the criticism and improving the PR.

This looks good to me, I think using process.exit is terrible in error situations, and it's already used in uncaughtException.

Copy link
Copy Markdown
Contributor

@breautek breautek left a comment

Choose a reason for hiding this comment

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

on commit fe053c8 can you amend the commit to include a line "Generated-by: Claude"

This is to satisfy Apache AI policy

When providing contributions authored using generative AI tooling, a recommended practice is for contributors to indicate the tooling used to create the contribution. This should be included as a token in the source control commit message, for example including the phrase “Generated-by: ”. This allows for future release tooling to be considered that pulls this content into a machine parsable Tooling-Provenance file.

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.

3 participants