-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
process: add unhandled-rejection throw and warn-with-error-code
This PR defines two new modes for the --unhandled-rejections flag. The first mode is called "throw". The "throw" mode first emits unhandledRejection. If this hook is not set, the "throw" mode will raise the unhandled rejection as an uncaught exception. The second mode is called "warn-with-error-code". The "warn-with-error-code" mode first emits unhandledRejection. If this hook is not set, the "warn-with-error-code" mode will trigger a warning and set the process's exit code to 1. The PR doesn't change the default behavior for unhandled rejections. That will come in a separate PR. Refs: #33021 PR-URL: #33475 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
- Loading branch information
1 parent
7169dc0
commit be300cf
Showing
7 changed files
with
164 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Flags: --unhandled-rejections=warn-with-error-code | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('assert'); | ||
|
||
common.disableCrashOnUnhandledRejection(); | ||
|
||
Promise.reject(new Error('alas')); | ||
process.on('exit', assert.strictEqual.bind(null, 1)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
*UnhandledPromiseRejectionWarning: Error: alas | ||
at *promise_unhandled_warn_with_error.js:*:* | ||
at * | ||
at * | ||
at * | ||
at * | ||
at * | ||
at * | ||
(Use `node --trace-warnings ...` to show where the warning was created) | ||
*UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Flags: --unhandled-rejections=throw | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const Countdown = require('../common/countdown'); | ||
const assert = require('assert'); | ||
|
||
common.disableCrashOnUnhandledRejection(); | ||
|
||
// Verify that the unhandledRejection handler prevents triggering | ||
// uncaught exceptions | ||
|
||
const err1 = new Error('One'); | ||
|
||
const errors = [err1, null]; | ||
|
||
const ref = new Promise(() => { | ||
throw err1; | ||
}); | ||
// Explicitly reject `null`. | ||
Promise.reject(null); | ||
|
||
process.on('warning', common.mustNotCall('warning')); | ||
process.on('rejectionHandled', common.mustNotCall('rejectionHandled')); | ||
process.on('exit', assert.strictEqual.bind(null, 0)); | ||
process.on('uncaughtException', common.mustNotCall('uncaughtException')); | ||
|
||
const timer = setTimeout(() => console.log(ref), 1000); | ||
|
||
const counter = new Countdown(2, () => { | ||
clearTimeout(timer); | ||
}); | ||
|
||
process.on('unhandledRejection', common.mustCall((err) => { | ||
counter.dec(); | ||
const knownError = errors.shift(); | ||
assert.deepStrictEqual(err, knownError); | ||
}, 2)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// Flags: --unhandled-rejections=throw | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const Countdown = require('../common/countdown'); | ||
const assert = require('assert'); | ||
|
||
common.disableCrashOnUnhandledRejection(); | ||
|
||
// Verify that unhandled rejections always trigger uncaught exceptions instead | ||
// of triggering unhandled rejections. | ||
|
||
const err1 = new Error('One'); | ||
const err2 = new Error( | ||
'This error originated either by throwing ' + | ||
'inside of an async function without a catch block, or by rejecting a ' + | ||
'promise which was not handled with .catch(). The promise rejected with the' + | ||
' reason "null".' | ||
); | ||
err2.code = 'ERR_UNHANDLED_REJECTION'; | ||
Object.defineProperty(err2, 'name', { | ||
value: 'UnhandledPromiseRejection', | ||
writable: true, | ||
configurable: true | ||
}); | ||
|
||
const errors = [err1, err2]; | ||
const identical = [true, false]; | ||
|
||
const ref = new Promise(() => { | ||
throw err1; | ||
}); | ||
// Explicitly reject `null`. | ||
Promise.reject(null); | ||
|
||
process.on('warning', common.mustNotCall('warning')); | ||
// If we add an unhandledRejection handler, the exception won't be thrown | ||
// process.on('unhandledRejection', common.mustCall(2)); | ||
process.on('rejectionHandled', common.mustNotCall('rejectionHandled')); | ||
process.on('exit', assert.strictEqual.bind(null, 0)); | ||
|
||
const timer = setTimeout(() => console.log(ref), 1000); | ||
|
||
const counter = new Countdown(2, () => { | ||
clearTimeout(timer); | ||
}); | ||
|
||
process.on('uncaughtException', common.mustCall((err, origin) => { | ||
counter.dec(); | ||
assert.strictEqual(origin, 'unhandledRejection', err); | ||
const knownError = errors.shift(); | ||
assert.deepStrictEqual(err, knownError); | ||
// Check if the errors are reference equal. | ||
assert(identical.shift() ? err === knownError : err !== knownError); | ||
}, 2)); |