From 0f493e9baf281c4c754cf48476aa3a27f91342c2 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Mon, 24 Jan 2022 20:47:11 +0200 Subject: [PATCH] process: unhandledRejection support more errors Support cross realm errors where `instanceof` errors in our unhandledRejection warning to print better error with stack traces. --- lib/internal/process/promises.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/internal/process/promises.js b/lib/internal/process/promises.js index 76099b1032a466..49445d258febe7 100644 --- a/lib/internal/process/promises.js +++ b/lib/internal/process/promises.js @@ -5,6 +5,7 @@ const { ArrayPrototypeShift, Error, ObjectDefineProperty, + ObjectPrototypeHasOwnProperty, SafeWeakMap, } = primordials; @@ -179,14 +180,21 @@ function emitUnhandledRejectionWarning(uid, reason) { `(rejection id: ${uid})` ); try { - if (reason instanceof Error) { + if (ObjectPrototypeHasOwnProperty(reason, 'stack')) { warning.stack = reason.stack; process.emitWarning(reason.stack, unhandledRejectionErrName); } else { process.emitWarning( noSideEffectsToString(reason), unhandledRejectionErrName); } - } catch {} + } catch { + try { + process.emitWarning( + noSideEffectsToString(reason), unhandledRejectionErrName); + } catch { + // Ignore. + } + } process.emitWarning(warning); } @@ -232,7 +240,7 @@ function processPromiseRejections() { try { switch (unhandledRejectionsMode) { case kStrictUnhandledRejections: { - const err = reason instanceof Error ? + const err = ObjectPrototypeHasOwnProperty(reason, 'stack') ? reason : generateUnhandledRejectionError(reason); // This destroys the async stack, don't clear it after triggerUncaughtException(err, true /* fromPromise */); @@ -259,7 +267,7 @@ function processPromiseRejections() { case kThrowUnhandledRejections: { const handled = emit(reason, promise, promiseInfo); if (!handled) { - const err = reason instanceof Error ? + const err = ObjectPrototypeHasOwnProperty(reason, 'stack') ? reason : generateUnhandledRejectionError(reason); // This destroys the async stack, don't clear it after triggerUncaughtException(err, true /* fromPromise */);