From a24ab56dc5119d456f7fe354a6ad558f304b64e2 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 5 Jul 2019 11:45:45 -0400 Subject: [PATCH] src: allow fatal exceptions to be enhanced This commit allows fatal exceptions to be enhanced so that exceptions thrown from an unhandledException handler have the stack attached properly. PR-URL: https://github.com/nodejs/node/pull/28562 Fixes: https://github.com/nodejs/node/issues/28550 Reviewed-By: Joyee Cheung Reviewed-By: Rich Trott Reviewed-By: Anna Henningsen --- src/node_errors.cc | 5 ++-- .../test-unhandled-exception-rethrow-error.js | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-unhandled-exception-rethrow-error.js diff --git a/src/node_errors.cc b/src/node_errors.cc index 298d84b4f362b3..0214521144c607 100644 --- a/src/node_errors.cc +++ b/src/node_errors.cc @@ -448,10 +448,11 @@ TryCatchScope::~TryCatchScope() { HandleScope scope(env_->isolate()); Local exception = Exception(); Local message = Message(); + EnhanceFatalException enhance = CanContinue() ? + EnhanceFatalException::kEnhance : EnhanceFatalException::kDontEnhance; if (message.IsEmpty()) message = Exception::CreateMessage(env_->isolate(), exception); - ReportFatalException( - env_, exception, message, EnhanceFatalException::kDontEnhance); + ReportFatalException(env_, exception, message, enhance); env_->Exit(7); } } diff --git a/test/parallel/test-unhandled-exception-rethrow-error.js b/test/parallel/test-unhandled-exception-rethrow-error.js new file mode 100644 index 00000000000000..a4d326d9839d71 --- /dev/null +++ b/test/parallel/test-unhandled-exception-rethrow-error.js @@ -0,0 +1,28 @@ +'use strict'; +require('../common'); + +if (process.argv[2] === 'child') { + process.on('uncaughtException', (err) => { + err.rethrow = true; + throw err; + }); + + function throwException() { + throw new Error('boom'); + } + + throwException(); +} else { + const assert = require('assert'); + const { spawnSync } = require('child_process'); + const result = spawnSync(process.execPath, [__filename, 'child']); + + assert.strictEqual(result.status, 7); + assert.strictEqual(result.signal, null); + assert.strictEqual(result.stdout.toString().trim(), ''); + // Verify that the error was thrown and that the stack was preserved. + const stderr = result.stderr.toString(); + assert(/Error: boom/.test(stderr)); + assert(/at throwException/.test(stderr)); + assert(/rethrow: true/.test(stderr)); +}