diff --git a/doc/api/process.md b/doc/api/process.md index 714a9bddc54fc1..07d9b43b55b8c5 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -97,6 +97,59 @@ the child process. The message goes through serialization and parsing. The resulting message might not be the same as what is originally sent. +### Event: 'multipleResolves' + + +* `type` {string} The error type. One of `'resolve'` or `'reject'`. +* `promise` {Promise} The promise that resolved or rejected more than once. +* `value` {any} The value with which the promise was either resolved or + rejected after the original resolve. + +The `'multipleResolves'` event is emitted whenever a `Promise` has been either: + +* Resolved more than once. +* Rejected more than once. +* Rejected after resolve. +* Resolved after reject. + +This is useful for tracking errors in your application while using the promise +constructor. Otherwise such mistakes are silently swallowed due to being in a +dead zone. + +It is recommended to end the process on such errors, since the process could be +in an undefined state. While using the promise constructor make sure that it is +guaranteed to trigger the `resolve()` or `reject()` functions exactly once per +call and never call both functions in the same call. + +```js +process.on('multipleResolves', (type, promise, reason) => { + console.error(type, promise, reason); + setImmediate(() => process.exit(1)); +}); + +async function main() { + try { + return await new Promise((resolve, reject) => { + resolve('First call'); + resolve('Swallowed resolve'); + reject(new Error('Swallowed reject')); + }); + } catch { + throw new Error('Failed'); + } +} + +main().then(console.log); +// resolve: Promise { 'First call' } 'Swallowed resolve' +// reject: Promise { 'First call' } Error: Swallowed reject +// at Promise (*) +// at new Promise () +// at main (*) +// First call +``` + ### Event: 'rejectionHandled'