worker: re-throw TerminationException from Bun__reportUnhandledError so terminate() breaks a microtask-bound ReadableStream loop - #36806
Open
robobun wants to merge 5 commits into
Claude / Claude Code Review
completed
Aug 3, 2026 in 23m 33s
Code review found 1 important issue
Found 3 candidates, confirmed 2. See review comments for details.
Details
| Severity | Count |
|---|---|
| 🔴 Important | 1 |
| 🟡 Nit | 1 |
| 🟣 Pre-existing | 0 |
| Severity | File:Line | Issue |
|---|---|---|
| 🔴 Important | src/jsc/virtual_machine_exports.rs:120-123 |
EventEmitter listener loop can trip assertNoException() after re-throwing TerminationException |
| 🟡 Nit | test/js/web/workers/worker-terminate-lifetime.test.ts:221-231 |
Dangling Bun.sleep(deadline) timers keep test subprocess alive after PASS |
Annotations
Check failure on line 123 in src/jsc/virtual_machine_exports.rs
claude / Claude Code Review
EventEmitter listener loop can trip assertNoException() after re-throwing TerminationException
Now that `Bun__reportUnhandledError` re-throws the TerminationException, `EventEmitter::innerInvokeEventListeners` (src/jsc/bindings/webcore/EventEmitter.cpp:259) can return from the report call with the exception pending and then continue the loop into the next listener's `JSC::call()`, tripping `executeCallImpl`'s `assertNoException()` and SIGABRTing the process in debug builds. Previously the report call was a no-op for termination, so this is a regression at that one caller — add a `if (vm.i
Check warning on line 231 in test/js/web/workers/worker-terminate-lifetime.test.ts
claude / Claude Code Review
Dangling Bun.sleep(deadline) timers keep test subprocess alive after PASS
The `Bun.sleep(${deadline})` loser of each `Promise.race` is never cancelled, so after `console.log("PASS")` the subprocess idles until the last-armed timer fires — ~4s on release, ~10s on debug/ASAN — before it can exit. Add `process.exit(0)` after `console.log("PASS")` (or race a clearable `setTimeout` and clear it when `terminate()` wins) to shave that dead time from every CI run.
Loading