Skip to content

Commit 9a9aa88

Browse files
MadaraUchihaMylesBorins
authored andcommitted
process: improve unhandled rejection message
PR-URL: #17158 Refs: #16768 Reviewed-By: Refael Ackermann <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]> Reviewed-By: Evan Lucas <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 5cbe0f2 commit 9a9aa88

5 files changed

+81
-14
lines changed

lib/internal/process/promises.js

+17-3
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,25 @@ function setupPromises(scheduleMicrotasks) {
6060
}
6161

6262
function emitWarning(uid, reason) {
63+
try {
64+
if (reason instanceof Error) {
65+
process.emitWarning(reason.stack, 'UnhandledPromiseRejectionWarning');
66+
} else {
67+
process.emitWarning(
68+
safeToString(reason), 'UnhandledPromiseRejectionWarning'
69+
);
70+
}
71+
} catch (e) {
72+
// ignored
73+
}
74+
6375
const warning = new Error(
64-
`Unhandled promise rejection (rejection id: ${uid}): ` +
65-
safeToString(reason));
76+
'Unhandled promise rejection. This error originated either by ' +
77+
'throwing inside of an async function without a catch block, ' +
78+
'or by rejecting a promise which was not handled with .catch(). ' +
79+
`(rejection id: ${uid})`
80+
);
6681
warning.name = 'UnhandledPromiseRejectionWarning';
67-
warning.id = uid;
6882
try {
6983
if (reason instanceof Error) {
7084
warning.stack = reason.stack;

test/message/unhandled_promise_trace_warnings.out

+18
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
(node:*) UnhandledPromiseRejectionWarning: Error: This was rejected
2+
at * (*test*message*unhandled_promise_trace_warnings.js:*)
3+
at *
4+
at *
5+
at *
6+
at *
7+
at *
8+
at *
9+
at *
10+
at *
11+
at *
12+
at *
13+
at *
14+
at *
15+
at *
16+
at *
17+
at *
18+
at *
119
(node:*) Error: This was rejected
220
at * (*test*message*unhandled_promise_trace_warnings.js:*)
321
at *

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ const expectedDeprecationWarning = 'Unhandled promise rejections are ' +
66
'rejections that are not handled will ' +
77
'terminate the Node.js process with a ' +
88
'non-zero exit code.';
9-
const expectedPromiseWarning = 'Unhandled promise rejection (rejection id: ' +
10-
'1): [object Object]';
9+
const expectedPromiseWarning = 'Unhandled promise rejection. ' +
10+
'This error originated either by throwing ' +
11+
'inside of an async function without a catch ' +
12+
'block, or by rejecting a promise which was ' +
13+
'not handled with .catch(). (rejection id: 1)';
1114

1215
function throwErr() {
1316
throw new Error('Error from proxy');

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

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,24 @@
11
'use strict';
22
const common = require('../common');
33

4+
const expectedValueWarning = 'Symbol()';
45
const expectedDeprecationWarning = 'Unhandled promise rejections are ' +
56
'deprecated. In the future, promise ' +
67
'rejections that are not handled will ' +
78
'terminate the Node.js process with a ' +
89
'non-zero exit code.';
9-
const expectedPromiseWarning = 'Unhandled promise rejection (rejection id: ' +
10-
'1): Symbol()';
10+
const expectedPromiseWarning = 'Unhandled promise rejection. ' +
11+
'This error originated either by throwing ' +
12+
'inside of an async function without a catch ' +
13+
'block, or by rejecting a promise which was ' +
14+
'not handled with .catch(). (rejection id: 1)';
1115

1216
common.expectWarning({
1317
DeprecationWarning: expectedDeprecationWarning,
14-
UnhandledPromiseRejectionWarning: expectedPromiseWarning,
18+
UnhandledPromiseRejectionWarning: [
19+
expectedPromiseWarning,
20+
expectedValueWarning
21+
],
1522
});
1623

1724
// ensure this doesn't crash

test/parallel/test-promises-warning-on-unhandled-rejection.js

+31-6
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,43 @@ let b = 0;
1212
process.on('warning', common.mustCall((warning) => {
1313
switch (b++) {
1414
case 0:
15-
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
16-
assert(/Unhandled promise rejection/.test(warning.message));
15+
// String rejection error displayed
16+
assert.strictEqual(warning.message, 'This was rejected');
1717
break;
1818
case 1:
19-
assert.strictEqual(warning.name, 'DeprecationWarning');
19+
// Warning about rejection not being handled (will be next tick)
20+
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
21+
assert(
22+
/Unhandled promise rejection/.test(warning.message),
23+
'Expected warning message to contain "Unhandled promise rejection" ' +
24+
'but did not. Had "' + warning.message + '" instead.'
25+
);
2026
break;
2127
case 2:
28+
// One time deprecation warning, first unhandled rejection
29+
assert.strictEqual(warning.name, 'DeprecationWarning');
30+
break;
31+
case 3:
32+
// Number rejection error displayed. Note it's been stringified
33+
assert.strictEqual(warning.message, '42');
34+
break;
35+
case 4:
36+
// Unhandled rejection warning (won't be handled next tick)
37+
assert.strictEqual(warning.name, 'UnhandledPromiseRejectionWarning');
38+
assert(
39+
/Unhandled promise rejection/.test(warning.message),
40+
'Expected warning message to contain "Unhandled promise rejection" ' +
41+
'but did not. Had "' + warning.message + '" instead.'
42+
);
43+
break;
44+
case 5:
45+
// Rejection handled asynchronously.
2246
assert.strictEqual(warning.name, 'PromiseRejectionHandledWarning');
2347
assert(/Promise rejection was handled asynchronously/
2448
.test(warning.message));
2549
}
26-
}, 3));
50+
}, 6));
2751

28-
const p = Promise.reject('This was rejected');
29-
setImmediate(common.mustCall(() => p.catch(() => {})));
52+
const p = Promise.reject('This was rejected'); // Reject with a string
53+
setImmediate(common.mustCall(() => p.catch(() => { })));
54+
Promise.reject(42); // Reject with a number

0 commit comments

Comments
 (0)