Skip to content

cli: return non-zero for uncaught runtime exceptions#4964

Open
SergioChan wants to merge 7 commits intoboa-dev:mainfrom
SergioChan:fix/issue-4962-exitcode
Open

cli: return non-zero for uncaught runtime exceptions#4964
SergioChan wants to merge 7 commits intoboa-dev:mainfrom
SergioChan:fix/issue-4962-exitcode

Conversation

@SergioChan
Copy link
Copy Markdown

This Pull Request fixes/closes #4962.

It changes the following:

  • Return an error from evaluate_file when script execution raises an uncaught runtime exception.
  • Preserve existing uncaught error printing, but propagate the failure so the CLI process exits non-zero.
  • Keep successful file execution behavior unchanged.

Validation

  • Not run locally in this environment because the Rust toolchain (cargo) is unavailable.
  • Behavioral check is directly aligned with issue reproduction: uncaught runtime errors now flow through an error return path instead of being swallowed with Ok(()).

@SergioChan SergioChan requested a review from a team as a code owner March 9, 2026 05:48
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 9, 2026

Test262 conformance changes

Test result main count PR count difference
Total 52,963 52,963 0
Passed 49,932 49,713 -219
Ignored 2,210 2,262 +52
Failed 821 988 +167
Panics 0 0 0
Conformance 94.28% 93.86% -0.41%
Fixed tests (2):
test/built-ins/RegExp/regexp-modifiers/remove-ignoreCase-affects-slash-upper-b.js (previously Failed)
test/built-ins/RegExp/regexp-modifiers/remove-ignoreCase-affects-slash-lower-b.js (previously Failed)
Broken tests (175):
test/intl402/supportedLocalesOf-test-option-localeMatcher.js (previously Passed)
test/intl402/supportedLocalesOf-returned-array-elements-are-not-frozen.js (previously Passed)
test/intl402/supportedLocalesOf-unicode-extensions-ignored.js (previously Passed)
test/intl402/supportedLocalesOf-default-locale-and-zxx-locale.js (previously Passed)
test/intl402/supportedLocalesOf-taint-Array-2.js (previously Passed)
test/intl402/supportedLocalesOf-empty-and-undefined.js (previously Passed)
test/intl402/default-locale-is-supported.js (previously Passed)
test/intl402/supportedLocalesOf-locales-arg-empty-array.js (previously Passed)
test/intl402/supportedLocalesOf-consistent-with-resolvedOptions.js (previously Passed)
test/intl402/supportedLocalesOf-taint-Array.js (previously Passed)
test/intl402/supportedLocalesOf-locales-arg-coered-to-object.js (previously Passed)
test/intl402/supportedLocalesOf-duplicate-elements-removed.js (previously Passed)
test/intl402/language-tags-canonicalized.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/length.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/basic.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/builtin.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/name.js (previously Passed)
test/intl402/DateTimeFormat/supportedLocalesOf/prop-desc.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lisu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Garay.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Extender.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Casemapped.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/XID_Continue.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tangut.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kaithi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Bengali.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tai_Yo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Decimal_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Beria_Erfe.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Common.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Uppercase.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Cyrillic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Lowercase.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Elbasan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kawi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Latin.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Permic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Khitan_Small_Script.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Case_Ignorable.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_NFKC_Casefolded.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Avestan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Carian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Titlecased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Meroitic_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Modifier_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Mongolian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Common.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kirat_Rai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sidetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gunjala_Gondi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Myanmar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Grapheme_Extend.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tulu_Tigalari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Extended_Pictographic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Cased_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Lowercase_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Latin.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gothic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tolong_Siki.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Gurung_Khema.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kawi.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Balinese.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Bopomofo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/ID_Start.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Thai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Myanmar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Georgian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Assigned.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Math.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Math_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Glagolitic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Turkic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Emoji_Presentation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Samaritan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Todhri.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Nonspacing_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Uppercased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Ideographic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sunuwar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Cased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Katakana.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Casefolded.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tibetan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Dash_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Cherokee.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Ethiopic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Beria_Erfe.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Changes_When_Lowercased.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Letter_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Telugu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Greek.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Adlam.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Han.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Mahajani.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Egyptian_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Ol_Onal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lycian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tolong_Siki.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sharada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tifinagh.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Garay.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Lydian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Phags_Pa.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Number.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Egyptian_Hieroglyphs.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Shavian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Telugu.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/ID_Continue.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Runic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tai_Yo.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Newa.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kirat_Rai.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Han.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Bidi_Mirrored.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Arabic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Dash.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Kannada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Ol_Onal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Coptic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Kannada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Todhri.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Nandinagari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Alphabetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Cyrillic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sunuwar.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Syriac.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Diacritic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Sentence_Terminal.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Osage.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Gurung_Khema.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tirhuta.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tangut.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Old_Hungarian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Tulu_Tigalari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Sharada.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Terminal_Punctuation.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Inherited.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Khitan_Small_Script.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Grapheme_Base.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Unassigned.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Toto.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Armenian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Tai_Le.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Devanagari.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Uppercase_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Arabic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/XID_Start.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Duployan.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Letter.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Spacing_Mark.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Sidetic.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Hebrew.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_Extensions_-_Caucasian_Albanian.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Balinese.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/General_Category_-_Currency_Symbol.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Script_-_Inherited.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/Unified_Ideograph.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji.js (previously Passed)
test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence.js (previously Passed)
test/built-ins/RegExp/regexp-modifiers/add-ignoreCase-affects-slash-upper-w.js (previously Passed)
test/built-ins/RegExp/regexp-modifiers/add-ignoreCase-affects-slash-lower-w.js (previously Passed)
test/built-ins/Object/freeze/typedarray-backed-by-resizable-buffer.js (previously Passed)
test/staging/sm/RegExp/unicode-ignoreCase.js (previously Passed)
test/staging/sm/RegExp/unicode-ignoreCase-word-boundary.js (previously Passed)

Tested main commit: 5ee4764a3f2b6c8d82a9cc7e9fd5206cfddde65d
Tested PR commit: b2116dfa24b5017b74e54d9c69686990f9b152a4
Compare commits: 5ee4764...b2116df

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 9, 2026

Codecov Report

❌ Patch coverage is 30.00000% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.74%. Comparing base (6ddc2b4) to head (4eb688a).
⚠️ Report is 804 commits behind head on main.

Files with missing lines Patch % Lines
cli/src/main.rs 30.00% 7 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main    #4964       +/-   ##
===========================================
+ Coverage   47.24%   58.74%   +11.50%     
===========================================
  Files         476      558       +82     
  Lines       46892    61380    +14488     
===========================================
+ Hits        22154    36059    +13905     
- Misses      24738    25321      +583     

☔ 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.

@jedel1043
Copy link
Copy Markdown
Member

I don't think this is fully working

boa git:(pr-4964) echo 'throw Error("nooo")' | cargo run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.13s
     Running `target/debug/boa`
Uncaught Error: Error: nooo (unknown at :1:12)
    at <main> (unknown at :1:12)
➜  boa git:(pr-4964) echo $?
0
➜  boa git:(pr-4964)

@jedel1043 jedel1043 added A-Bug Something isn't working C-CLI Issues and PRs related to the Boa command line interface. Waiting On Author Waiting on PR changes from the author labels Mar 11, 2026
@SergioChan
Copy link
Copy Markdown
Author

Thanks for the repro — you were right.

The previous patch only returned a non-zero status for file execution errors. stdin / -e still went through evaluate_expr, which printed the uncaught error but returned Ok(()).

I pushed a follow-up commit that propagates those errors out of evaluate_expr as well:

  • commit: 81d20ff
  • PR branch: fix/issue-4962-exitcode

What changed:

  • return Err(...) on script parse/eval failures in evaluate_expr
  • return Err(...) when context.run_jobs() fails in evaluate_expr

Validation note:

  • I could not run the local CLI repro in this environment because the Rust toolchain (cargo) is unavailable here.
  • Please rely on CI for execution validation; if you want, I can add a targeted regression test once I have a toolchain-enabled environment.

@jedel1043
Copy link
Copy Markdown
Member

Yeah a test would be ideal, using something like assert_cmd

@SergioChan
Copy link
Copy Markdown
Author

Great call — I added integration regression coverage using assert_cmd.

What I changed

  • Added assert_cmd as a dev dependency for boa_cli.
  • Added cli/tests/exit_code.rs with two regression tests:
    • stdin_uncaught_error_exits_non_zero
    • expression_uncaught_error_exits_non_zero
  • Both assert that uncaught runtime exceptions produce a non-zero process exit code for stdin and -e execution paths.

Validation

  • I couldn't execute cargo test in this environment because the Rust toolchain (cargo) is unavailable here.
  • The tests are committed and CI should validate them on the PR branch.

@SergioChan
Copy link
Copy Markdown
Author

Pushed follow-up commit 8dc5d133 to address CI/lint blockers from the regression test addition.

What changed

  • Added crate-level allowances in cli/tests/exit_code.rs for strict test-target lint settings:
    • missing_docs
    • unused_crate_dependencies
  • Added a test-only import in cli/src/main.rs:
    • #[cfg(test)] use assert_cmd as _;
      This satisfies unused-crate-dependencies for the binary test target.

This keeps the assert_cmd regression tests while matching the repo's -D warnings policy. Please take another look.

@jedel1043
Copy link
Copy Markdown
Member

You also need to commit your changes to the Cargo.lock, since you added a new dependency.

@SergioChan
Copy link
Copy Markdown
Author

Thanks for the review. I鈥檓 working through the requested updates and will post a focused patch shortly.

cli/src/main.rs Outdated
Err(ref v) => printer.print(uncaught_error(v)),
Err(v) => {
printer.print(uncaught_error(&v));
return Err(v.into_erased(context).into());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tested the code and directly returning the error makes it show up two times in stderr. We might have to adjust the returned error such that it doesn't reference the already printed error.

@SergioChan
Copy link
Copy Markdown
Author

Thanks for the pointer on Cargo.lock.

I pushed commit b2116dfa to avoid introducing a new dependency in cli tests:

  • removed assert_cmd from cli/Cargo.toml
  • removed the test-only assert_cmd import from cli/src/main.rs
  • rewrote cli/tests/exit_code.rs to use std::process::Command + CARGO_BIN_EXE_boa

This keeps the same regression coverage (stdin and -e uncaught errors return non-zero) while avoiding lockfile churn.

Validation run in this update:

  • git diff --check (clean)

I couldn’t run cargo test in this environment because the Rust toolchain is not available, so CI is needed for execution validation.

@jedel1043
Copy link
Copy Markdown
Member

You didn't address my comment though

@jedel1043 jedel1043 added this to the v1.0.0 milestone Mar 16, 2026
@SergioChan
Copy link
Copy Markdown
Author

You’re absolutely right — I missed that thread. Thanks for the nudge.

I’ll address your remaining comment directly and push a follow-up patch shortly.

@github-actions github-actions bot added C-Tests Issues and PRs related to the tests. C-Builtins PRs and Issues related to builtins/intrinsics labels Mar 19, 2026
@SergioChan
Copy link
Copy Markdown
Author

Thanks for the follow-up — I tracked down the missed review point about duplicated stderr output.

I just pushed 62e25c9.

What changed

  • In evaluate_expr, keep printing the uncaught parse/runtime/job error once via the existing printer.
  • Return a concise sentinel error (parsing failed / execution failed) instead of re-wrapping the original JS error object.

This preserves the non-zero exit behavior while avoiding duplicated detailed error text in stderr.

Validation

  • git diff --check (clean)
  • I could not run cargo test here because the Rust toolchain is unavailable in this environment, so CI is needed for execution validation.

@SergioChan
Copy link
Copy Markdown
Author

Quick follow-up on the outstanding changes-requested thread: commit 62e25c9 keeps the uncaught-error printing path but returns sentinel errors to avoid duplicated stderr output, while preserving non-zero exits.\n\n@jedel1043 could you re-check this when you have time and confirm whether this resolves your remaining concern?

@SergioChan
Copy link
Copy Markdown
Author

Quick follow-up on the CHANGES_REQUESTED items: I switched the -e/stdin paths to return a short eyre!(...) after printing the uncaught error so we avoid bubbling the full engine error twice on stderr, while keeping evaluate_file propagation as-is for file execution semantics.\n\nCould you re-check if this matches what you had in mind, or should I also switch the file path to a shortened propagated error?

@SergioChan
Copy link
Copy Markdown
Author

Pushed follow-up commit 17c35d59 to address the duplicate-stderr behavior in file execution and align all execution modes.

What changed

  • In evaluate_file, after printing the uncaught error, return a short sentinel error (execution failed) instead of bubbling the full JS error object again.
  • Added a regression test file_uncaught_error_exits_non_zero in cli/tests/exit_code.rs to cover script-file execution explicitly.

Why

This keeps the non-zero exit behavior from #4962 while avoiding duplicate detailed error output on stderr in the file path (matching the stdin / -e handling).

Validation

  • git diff --check (clean)
  • Could not run cargo test here because cargo is unavailable in this environment, so CI is needed for execution validation.

@SergioChan SergioChan force-pushed the fix/issue-4962-exitcode branch from 17c35d5 to fa38eac Compare March 21, 2026 03:56
@SergioChan
Copy link
Copy Markdown
Author

Quick update: I rebased this branch onto the latest main and force-pushed to refresh the PR tip (fa38eac5).

What changed

  • Replayed the existing fix commits on top of current main.
  • No intentional functional changes beyond the rebase; this is to keep the branch current for review/merge.

Validation

  • git diff --check upstream/main...HEAD
  • I couldn’t run cargo test here because cargo is not available in this runtime; CI should provide execution validation.

@SergioChan SergioChan force-pushed the fix/issue-4962-exitcode branch from fa38eac to be429ba Compare March 21, 2026 21:41
@SergioChan
Copy link
Copy Markdown
Author

Rebased this branch onto the latest main again and force-pushed the refreshed head (be429baf).

No intentional functional changes were made in this update; this was a branch-refresh push to keep the PR current for review.

Validation in this run:

  • git diff --check upstream/main...HEAD
  • cargo test -p boa_cli --test exit_code -- --nocapture (not runnable here: cargo is unavailable in this environment)

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

Labels

A-Bug Something isn't working C-Builtins PRs and Issues related to builtins/intrinsics C-CLI Issues and PRs related to the Boa command line interface. C-Tests Issues and PRs related to the tests. Waiting On Author Waiting on PR changes from the author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

boa_cli exit code 0 on uncaught runtime exceptions

2 participants