Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 36.4k
process: refactor promise rejection handling#25200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
a9bd4b08f78021bdad2db4a6765bFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,24 +2,46 @@ | ||
| const { safeToString } = internalBinding('util'); | ||
| const { | ||
| promiseRejectEvents | ||
| tickInfo, | ||
| promiseRejectEvents: { | ||
| kPromiseRejectWithNoHandler, | ||
| kPromiseHandlerAddedAfterReject, | ||
| kPromiseResolveAfterResolved, | ||
| kPromiseRejectAfterResolved | ||
| }, | ||
| setPromiseRejectCallback | ||
| } = internalBinding('task_queue'); | ||
| // *Must* match Environment::TickInfo::Fields in src/env.h. | ||
| const kHasRejectionToWarn = 1; | ||
| const maybeUnhandledPromises = new WeakMap(); | ||
| const pendingUnhandledRejections = []; | ||
| const asyncHandledRejections = []; | ||
| let lastPromiseId = 0; | ||
| function setHasRejectionToWarn(value) { | ||
| tickInfo[kHasRejectionToWarn] = value ? 1 : 0; | ||
| } | ||
| function hasRejectionToWarn() { | ||
| return tickInfo[kHasRejectionToWarn] === 1; | ||
| } | ||
| function promiseRejectHandler(type, promise, reason) { | ||
| switch (type) { | ||
| case promiseRejectEvents.kPromiseRejectWithNoHandler: | ||
| return unhandledRejection(promise, reason); | ||
| case promiseRejectEvents.kPromiseHandlerAddedAfterReject: | ||
| return handledRejection(promise); | ||
| case promiseRejectEvents.kPromiseResolveAfterResolved: | ||
| return resolveError('resolve', promise, reason); | ||
| case promiseRejectEvents.kPromiseRejectAfterResolved: | ||
| return resolveError('reject', promise, reason); | ||
| case kPromiseRejectWithNoHandler: | ||
| unhandledRejection(promise, reason); | ||
| break; | ||
| case kPromiseHandlerAddedAfterReject: | ||
| handledRejection(promise); | ||
| break; | ||
| case kPromiseResolveAfterResolved: | ||
| resolveError('resolve', promise, reason); | ||
| break; | ||
| case kPromiseRejectAfterResolved: | ||
| resolveError('reject', promise, reason); | ||
| break; | ||
| } | ||
| } | ||
| @@ -38,7 +60,7 @@ function unhandledRejection(promise, reason) { | ||
| warned: false | ||
| }); | ||
| pendingUnhandledRejections.push(promise); | ||
| return true; | ||
| setHasRejectionToWarn(true); | ||
| } | ||
| function handledRejection(promise) { | ||
| @@ -54,10 +76,11 @@ function handledRejection(promise) { | ||
| warning.name = 'PromiseRejectionHandledWarning'; | ||
| warning.id = uid; | ||
| asyncHandledRejections.push({ promise, warning }); | ||
| return true; | ||
| setHasRejectionToWarn(true); | ||
| return; | ||
| } | ||
| } | ||
joyeecheung marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| return false; | ||
| setHasRejectionToWarn(false); | ||
| } | ||
| const unhandledRejectionErrName = 'UnhandledPromiseRejectionWarning'; | ||
| @@ -95,7 +118,9 @@ function emitDeprecationWarning() { | ||
| } | ||
| } | ||
| function emitPromiseRejectionWarnings() { | ||
| // If this method returns true, at least one more tick need to be | ||
| // scheduled to process any potential pending rejections | ||
| function processPromiseRejections() { | ||
| while (asyncHandledRejections.length > 0) { | ||
| const { promise, warning } = asyncHandledRejections.shift(); | ||
| if (!process.emit('rejectionHandled', promise)) { | ||
| @@ -120,7 +145,13 @@ function emitPromiseRejectionWarnings() { | ||
| return maybeScheduledTicks || pendingUnhandledRejections.length !== 0; | ||
| } | ||
| function listenForRejections() { | ||
| setPromiseRejectCallback(promiseRejectHandler); | ||
joyeecheung marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| module.exports = { | ||
| promiseRejectHandler, | ||
| emitPromiseRejectionWarnings | ||
| hasRejectionToWarn, | ||
| setHasRejectionToWarn, | ||
| listenForRejections, | ||
| processPromiseRejections | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -241,6 +241,10 @@ Environment::Environment(IsolateData* isolate_data, | ||
| if (options_->no_force_async_hooks_checks) { | ||
| async_hooks_.no_force_checks(); | ||
| } | ||
| // TODO(addaleax): the per-isolate state should not be controlled by | ||
| // a single Environment. | ||
| isolate()->SetPromiseRejectCallback(task_queue::PromiseRejectCallback); | ||
Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you leave a TODO comment for me? We’re letting a single MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity - when would multiple | ||
| } | ||
| Environment::~Environment() { | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.