Skip to content

fix(ext/node): wrap non-Error unhandled rejections in ERR_UNHANDLED_REJECTION#32535

Merged
bartlomieju merged 4 commits intomainfrom
fix/wrap-non-error-unhandled-rejection
Mar 12, 2026
Merged

fix(ext/node): wrap non-Error unhandled rejections in ERR_UNHANDLED_REJECTION#32535
bartlomieju merged 4 commits intomainfrom
fix/wrap-non-error-unhandled-rejection

Conversation

@bartlomieju
Copy link
Copy Markdown
Member

Summary

  • When a promise is rejected with a non-Error value (e.g. Promise.reject(null)) and there are no unhandledRejection listeners, Node.js wraps the rejection reason in an ERR_UNHANDLED_REJECTION error before routing it to uncaughtException. Deno was passing the raw value directly, which caused crashes when exception handlers accessed .message or .name.
  • This fixes test-promise-unhandled-default.js in the node compat test suite (also unblocks test-promise-unhandled-throw.js which tests the same wrapping logic under --unhandled-rejections=throw).

Test plan

  • cargo test --test node_compat test-promise-unhandled-default passes (was failing before)
  • Full promise test suite: went from 16/20 failing to 14/20 failing (remaining failures are due to missing v8.promiseHooks, --unhandled-rejections flag, and process.on('multipleResolves'))

🤖 Generated with Claude Code

bartlomieju and others added 2 commits March 6, 2026 11:28
…EJECTION

When a promise is rejected with a non-Error value (e.g. `Promise.reject(null)`)
and there are no `unhandledRejection` listeners, Node.js wraps the rejection
reason in an `ERR_UNHANDLED_REJECTION` error before passing it to
`uncaughtException`. Deno was passing the raw value directly, causing crashes
when handlers tried to access `.message` or `.name` on the reason.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bartlomieju bartlomieju requested a review from littledivy March 11, 2026 07:49
Copy link
Copy Markdown
Contributor

@kajukitli kajukitli left a comment

Choose a reason for hiding this comment

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

lgtm, clean fix

wrapping non-Error rejections in ERR_UNHANDLED_REJECTION matches Node.js behavior. the message format looks correct too.

one minor note: you might want to preserve the original rejection value somewhere on the error (Node.js uses err.reason for this I think). but if the test passes without it, probably fine for now.

Node.js attaches the original rejection reason as a `reason` property
on the wrapped ERR_UNHANDLED_REJECTION error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@bartlomieju bartlomieju requested a review from nathanwhit March 12, 2026 09:53
Copy link
Copy Markdown
Member

@nathanwhit nathanwhit left a comment

Choose a reason for hiding this comment

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

LGTM

@bartlomieju bartlomieju merged commit 2353a5a into main Mar 12, 2026
112 checks passed
@bartlomieju bartlomieju deleted the fix/wrap-non-error-unhandled-rejection branch March 12, 2026 18:08
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