Skip to content

Commit e46e34b

Browse files
committed
process: Change default --unhandled-rejections=warn-with-error-code
This is a semver-major change that resolves DEP0018. In addition to changing the default value for --unhandled-rejections, this PR changes the exit code from 1 to 66. The warning message has been updated to mention the new exit code, which I selected in order to make this problem easier to search for on the web. Users can prevent this behavior by setting a non-default value for the --unhandled-rejections flag (throw, strict, warn, or none) or by setting a hook for 'unhandledRejection'. This change has no effect on users who have already set the flag or installed an 'unhandledRejection' hook; it will only impact users who currently see a DEP0018 warning today.
1 parent 14d012e commit e46e34b

12 files changed

+27
-68
lines changed

doc/api/cli.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -978,20 +978,17 @@ added:
978978
- v10.17.0
979979
-->
980980

981-
By default all unhandled rejections trigger a warning plus a deprecation warning
982-
for the very first unhandled rejection in case no [`unhandledRejection`][] hook
983-
is used.
984-
985981
Using this flag allows to change what should happen when an unhandled rejection
986982
occurs. One of the following modes can be chosen:
987983

984+
* `warn-with-error-code`: Emit [`unhandledRejection`][]. If this hook is not
985+
set, trigger a warning, and set the process exit code to 66. This is the
986+
default.
988987
* `throw`: Emit [`unhandledRejection`][]. If this hook is not set, raise the
989988
unhandled rejection as an uncaught exception.
990989
* `strict`: Raise the unhandled rejection as an uncaught exception.
991990
* `warn`: Always trigger a warning, no matter if the [`unhandledRejection`][]
992991
hook is set or not but do not print the deprecation warning.
993-
* `warn-with-error-code`: Emit [`unhandledRejection`][]. If this hook is not
994-
set, trigger a warning, and set the process exit code to 1.
995992
* `none`: Silence all warnings.
996993

997994
### `--use-bundled-ca`, `--use-openssl-ca`

lib/internal/process/promises.js

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,11 @@ const kThrowUnhandledRejections = 3;
5353

5454
// --unhandled-rejections=warn-with-error-code:
5555
// Emit 'unhandledRejection', if it's unhandled, emit
56-
// 'UnhandledPromiseRejectionWarning', then set process exit code to 1.
56+
// 'UnhandledPromiseRejectionWarning', then set process exit code to 66.
5757

5858
const kWarnWithErrorCodeUnhandledRejections = 4;
5959

60-
// --unhandled-rejections is unset:
61-
// Emit 'unhandledRejection', if it's unhandled, emit
62-
// 'UnhandledPromiseRejectionWarning', then emit deprecation warning.
63-
const kDefaultUnhandledRejections = 5;
60+
const unhandledRejectionExitCode = 66;
6461

6562
let unhandledRejectionsMode;
6663

@@ -86,7 +83,7 @@ function getUnhandledRejectionsMode() {
8683
case 'warn-with-error-code':
8784
return kWarnWithErrorCodeUnhandledRejections;
8885
default:
89-
return kDefaultUnhandledRejections;
86+
return kWarnWithErrorCodeUnhandledRejections;
9087
}
9188
}
9289

@@ -151,12 +148,14 @@ function handledRejection(promise) {
151148
}
152149

153150
const unhandledRejectionErrName = 'UnhandledPromiseRejectionWarning';
154-
function emitUnhandledRejectionWarning(uid, reason) {
151+
function emitUnhandledRejectionWarning(uid, reason, failing) {
155152
const warning = getErrorWithoutStack(
156153
unhandledRejectionErrName,
157154
'Unhandled promise rejection. This error originated either by ' +
158155
'throwing inside of an async function without a catch block, ' +
159156
'or by rejecting a promise which was not handled with .catch(). ' +
157+
(failing ? 'This process will terminate with exit code ' +
158+
unhandledRejectionExitCode + '. ' : '') +
160159
'To terminate the node process on unhandled promise ' +
161160
'rejection, use the CLI flag `--unhandled-rejections=strict` (see ' +
162161
'https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). ' +
@@ -175,15 +174,6 @@ function emitUnhandledRejectionWarning(uid, reason) {
175174
process.emitWarning(warning);
176175
}
177176

178-
let deprecationWarned = false;
179-
function emitDeprecationWarning() {
180-
process.emitWarning(
181-
'Unhandled promise rejections are deprecated. In the future, ' +
182-
'promise rejections that are not handled will terminate the ' +
183-
'Node.js process with a non-zero exit code.',
184-
'DeprecationWarning', 'DEP0018');
185-
}
186-
187177
// If this method returns true, we've executed user code or triggered
188178
// a warning to be emitted which requires the microtask and next tick
189179
// queues to be drained again.
@@ -236,19 +226,8 @@ function processPromiseRejections() {
236226
case kWarnWithErrorCodeUnhandledRejections: {
237227
const handled = process.emit('unhandledRejection', reason, promise);
238228
if (!handled) {
239-
emitUnhandledRejectionWarning(uid, reason);
240-
process.exitCode = 1;
241-
}
242-
break;
243-
}
244-
case kDefaultUnhandledRejections: {
245-
const handled = process.emit('unhandledRejection', reason, promise);
246-
if (!handled) {
247-
emitUnhandledRejectionWarning(uid, reason);
248-
if (!deprecationWarned) {
249-
emitDeprecationWarning();
250-
deprecationWarned = true;
251-
}
229+
emitUnhandledRejectionWarning(uid, reason, true /* failing */);
230+
process.exitCode = unhandledRejectionExitCode;
252231
}
253232
break;
254233
}

test/es-module/test-esm-cjs-load-error-note.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const expectedNote = 'To load an ES module, ' +
1717
'or use the .mjs extension.';
1818

1919
const expectedCode = 1;
20+
const expectedUnhandledRejectionCode = 66;
2021

2122
const pExport1 = spawn(process.execPath, [Export1]);
2223
let pExport1Stderr = '';
@@ -63,8 +64,7 @@ pImport2.stderr.on('data', (data) => {
6364
pImport2Stderr += data;
6465
});
6566
pImport2.on('close', mustCall((code) => {
66-
// As this exits normally we expect 0
67-
assert.strictEqual(code, 0);
67+
assert.strictEqual(code, expectedUnhandledRejectionCode);
6868
assert.ok(!pImport2Stderr.includes(expectedNote),
6969
`${expectedNote} must not be included in ${pImport2Stderr}`);
7070
}));
@@ -94,15 +94,15 @@ pImport4.on('close', mustCall((code) => {
9494
`${expectedNote} not found in ${pImport4Stderr}`);
9595
}));
9696

97-
// Must exit with zero and show note
97+
// Must exit with 66 and show note
9898
const pImport5 = spawn(process.execPath, [Import5]);
9999
let pImport5Stderr = '';
100100
pImport5.stderr.setEncoding('utf8');
101101
pImport5.stderr.on('data', (data) => {
102102
pImport5Stderr += data;
103103
});
104104
pImport5.on('close', mustCall((code) => {
105-
assert.strictEqual(code, 0);
105+
assert.strictEqual(code, expectedUnhandledRejectionCode);
106106
assert.ok(!pImport5Stderr.includes(expectedNote),
107107
`${expectedNote} must not be included in ${pImport5Stderr}`);
108108
}));

test/message/promise_unhandled_warn_with_error.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ const assert = require('assert');
77
common.disableCrashOnUnhandledRejection();
88

99
Promise.reject(new Error('alas'));
10-
process.on('exit', assert.strictEqual.bind(null, 1));
10+
process.on('exit', assert.strictEqual.bind(null, 66));

test/message/promise_unhandled_warn_with_error.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
at *
88
at *
99
(Use `node --trace-warnings ...` to show where the warning was created)
10-
*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)
10+
*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(). This process will terminate with exit code 66. 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)

test/message/unhandled_promise_trace_warnings.out

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@
1717
at *
1818
at *
1919
at *
20-
(node:*) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
21-
at *
22-
at *
23-
at *
2420
(node:*) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
2521
at handledRejection (internal/process/promises.js:*)
2622
at promiseRejectHandler (internal/process/promises.js:*)

test/parallel/test-async-wrap-pop-id-during-load.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const ret = spawnSync(
1919
['--stack_size=150', __filename, 'async'],
2020
{ maxBuffer: Infinity }
2121
);
22-
assert.strictEqual(ret.status, 0,
22+
assert.strictEqual(ret.status, 66,
2323
`EXIT CODE: ${ret.status}, STDERR:\n${ret.stderr}`);
2424
const stderr = ret.stderr.toString('utf8', 0, 2048);
2525
assert.ok(!/async.*hook/i.test(stderr));

test/parallel/test-promises-unhandled-proxy-rejections.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1+
// Flags: --unhandled-rejections=warn
12
'use strict';
23
const common = require('../common');
34

45
common.disableCrashOnUnhandledRejection();
56

6-
const expectedDeprecationWarning = ['Unhandled promise rejections are ' +
7-
'deprecated. In the future, promise ' +
8-
'rejections that are not handled will ' +
9-
'terminate the Node.js process with a ' +
10-
'non-zero exit code.', 'DEP0018'];
117
const expectedPromiseWarning = ['Unhandled promise rejection. ' +
128
'This error originated either by throwing ' +
139
'inside of an async function without a catch ' +
@@ -39,7 +35,6 @@ const thorny = new Proxy({}, {
3935
});
4036

4137
common.expectWarning({
42-
DeprecationWarning: expectedDeprecationWarning,
4338
UnhandledPromiseRejectionWarning: expectedPromiseWarning,
4439
});
4540

test/parallel/test-promises-unhandled-rejections.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// Flags: --unhandled-rejections=warn
12
'use strict';
23
const common = require('../common');
34
const assert = require('assert');
@@ -714,7 +715,7 @@ asyncTest(
714715
done();
715716
}
716717
emitWarning(...args);
717-
}, 2);
718+
}, 4);
718719

719720
let timer = setTimeout(common.mustNotCall(), 10000);
720721
},

test/parallel/test-promises-unhandled-symbol-rejections.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1+
// Flags: --unhandled-rejections=warn
12
'use strict';
23
const common = require('../common');
34

45
common.disableCrashOnUnhandledRejection();
56

67
const expectedValueWarning = ['Symbol()'];
7-
const expectedDeprecationWarning = ['Unhandled promise rejections are ' +
8-
'deprecated. In the future, promise ' +
9-
'rejections that are not handled will ' +
10-
'terminate the Node.js process with a ' +
11-
'non-zero exit code.', 'DEP0018'];
128
const expectedPromiseWarning = ['Unhandled promise rejection. ' +
139
'This error originated either by throwing ' +
1410
'inside of an async function without a catch ' +
@@ -20,7 +16,6 @@ const expectedPromiseWarning = ['Unhandled promise rejection. ' +
2016
'(rejection id: 1)'];
2117

2218
common.expectWarning({
23-
DeprecationWarning: expectedDeprecationWarning,
2419
UnhandledPromiseRejectionWarning: [
2520
expectedValueWarning,
2621
expectedPromiseWarning

0 commit comments

Comments
 (0)