Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ee61bc7

Browse filesBrowse files
benjamingrdanielleadams
authored andcommitted
process: unhandledRejection support more errors
Support cross realm errors where `instanceof` errors in our unhandledRejection warning to print better error with stack traces. PR-URL: #41682 Refs: #41676 Reviewed-By: Nitzan Uziely <linkgoron@gmail.com> Reviewed-By: Tierney Cyren <hello@bnb.im>
1 parent db1ce43 commit ee61bc7
Copy full SHA for ee61bc7

File tree

Expand file treeCollapse file tree

2 files changed

+35
-6
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+35
-6
lines changed
Open diff view settings
Collapse file

‎lib/internal/process/promises.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/promises.js
+18-4Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
ArrayPrototypeShift,
66
Error,
77
ObjectDefineProperty,
8+
ObjectPrototypeHasOwnProperty,
89
SafeWeakMap,
910
} = primordials;
1011

@@ -79,6 +80,12 @@ function hasRejectionToWarn() {
7980
return tickInfo[kHasRejectionToWarn] === 1;
8081
}
8182

83+
function isErrorLike(o) {
84+
return typeof o === 'object' &&
85+
o !== null &&
86+
ObjectPrototypeHasOwnProperty(o, 'stack');
87+
}
88+
8289
function getUnhandledRejectionsMode() {
8390
const { getOptionValue } = require('internal/options');
8491
switch (getOptionValue('--unhandled-rejections')) {
@@ -179,14 +186,21 @@ function emitUnhandledRejectionWarning(uid, reason) {
179186
`(rejection id: ${uid})`
180187
);
181188
try {
182-
if (reason instanceof Error) {
189+
if (isErrorLike(reason)) {
183190
warning.stack = reason.stack;
184191
process.emitWarning(reason.stack, unhandledRejectionErrName);
185192
} else {
186193
process.emitWarning(
187194
noSideEffectsToString(reason), unhandledRejectionErrName);
188195
}
189-
} catch {}
196+
} catch {
197+
try {
198+
process.emitWarning(
199+
noSideEffectsToString(reason), unhandledRejectionErrName);
200+
} catch {
201+
// Ignore.
202+
}
203+
}
190204

191205
process.emitWarning(warning);
192206
}
@@ -232,7 +246,7 @@ function processPromiseRejections() {
232246
try {
233247
switch (unhandledRejectionsMode) {
234248
case kStrictUnhandledRejections: {
235-
const err = reason instanceof Error ?
249+
const err = isErrorLike(reason) ?
236250
reason : generateUnhandledRejectionError(reason);
237251
// This destroys the async stack, don't clear it after
238252
triggerUncaughtException(err, true /* fromPromise */);
@@ -259,7 +273,7 @@ function processPromiseRejections() {
259273
case kThrowUnhandledRejections: {
260274
const handled = emit(reason, promise, promiseInfo);
261275
if (!handled) {
262-
const err = reason instanceof Error ?
276+
const err = isErrorLike(reason) ?
263277
reason : generateUnhandledRejectionError(reason);
264278
// This destroys the async stack, don't clear it after
265279
triggerUncaughtException(err, true /* fromPromise */);
Collapse file

‎test/parallel/test-promise-unhandled-warn.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-promise-unhandled-warn.js
+17-2Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
'use strict';
33

44
const common = require('../common');
5+
const assert = require('assert');
56

67
// Verify that ignoring unhandled rejection works fine and that no warning is
78
// logged.
@@ -12,11 +13,25 @@ new Promise(() => {
1213

1314
Promise.reject('test');
1415

16+
function lookForMeInStackTrace() {
17+
Promise.reject(new class ErrorLike {
18+
constructor() {
19+
Error.captureStackTrace(this);
20+
this.message = 'ErrorLike';
21+
}
22+
}());
23+
}
24+
lookForMeInStackTrace();
25+
1526
// Unhandled rejections trigger two warning per rejection. One is the rejection
1627
// reason and the other is a note where this warning is coming from.
17-
process.on('warning', common.mustCall(4));
28+
process.on('warning', common.mustCall((reason) => {
29+
if (reason.message.includes('ErrorLike')) {
30+
assert.match(reason.stack, /lookForMeInStackTrace/);
31+
}
32+
}, 6));
1833
process.on('uncaughtException', common.mustNotCall('uncaughtException'));
19-
process.on('rejectionHandled', common.mustCall(2));
34+
process.on('rejectionHandled', common.mustCall(3));
2035

2136
process.on('unhandledRejection', (reason, promise) => {
2237
// Handle promises but still warn!

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.