mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
events: change EventTarget handler exception behavior
Change the behavior of EventTarget, instead of emitting 'error' on handler exception, emit 'uncaughtException'. Fixes: https://github.com/nodejs/node/issues/36770 PR-URL: https://github.com/nodejs/node/pull/37237 Fixes: https://github.com/nodejs/node/issues/36770 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit is contained in:
parent
98037294d2
commit
83d6e63aee
@ -1137,6 +1137,9 @@ setMaxListeners(5, target, emitter);
|
||||
<!-- YAML
|
||||
added: v14.5.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/37237
|
||||
description: changed EventTarget error handling.
|
||||
- version: v15.4.0
|
||||
pr-url: https://github.com/nodejs/node/pull/35949
|
||||
description: No longer experimental.
|
||||
|
||||
@ -459,9 +459,9 @@ class EventTarget {
|
||||
result = FunctionPrototypeCall(callback, this, arg);
|
||||
}
|
||||
if (result !== undefined && result !== null)
|
||||
addCatch(this, result, createEvent());
|
||||
addCatch(result);
|
||||
} catch (err) {
|
||||
emitUnhandledRejectionOrErr(this, err, createEvent());
|
||||
emitUncaughtException(err);
|
||||
}
|
||||
|
||||
handler = next;
|
||||
@ -624,19 +624,19 @@ function isEventTarget(obj) {
|
||||
return obj?.constructor?.[kIsEventTarget];
|
||||
}
|
||||
|
||||
function addCatch(that, promise, event) {
|
||||
function addCatch(promise) {
|
||||
const then = promise.then;
|
||||
if (typeof then === 'function') {
|
||||
FunctionPrototypeCall(then, promise, undefined, function(err) {
|
||||
// The callback is called with nextTick to avoid a follow-up
|
||||
// rejection from this promise.
|
||||
process.nextTick(emitUnhandledRejectionOrErr, that, err, event);
|
||||
emitUncaughtException(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function emitUnhandledRejectionOrErr(that, err, event) {
|
||||
process.emit('error', err, event);
|
||||
function emitUncaughtException(err) {
|
||||
process.nextTick(() => { throw err; });
|
||||
}
|
||||
|
||||
function makeEventHandler(handler) {
|
||||
|
||||
@ -178,14 +178,16 @@ let asyncTest = Promise.resolve();
|
||||
}
|
||||
|
||||
{
|
||||
const uncaughtException = common.mustCall((err, event) => {
|
||||
const uncaughtException = common.mustCall((err, origin) => {
|
||||
strictEqual(err.message, 'boom');
|
||||
strictEqual(event.type, 'foo');
|
||||
strictEqual(origin, 'uncaughtException');
|
||||
}, 4);
|
||||
|
||||
// Whether or not the handler function is async or not, errors
|
||||
// are routed to uncaughtException
|
||||
process.on('error', uncaughtException);
|
||||
// Make sure that we no longer call 'error' on error.
|
||||
process.on('error', common.mustNotCall());
|
||||
// Don't call rejection even for async handlers.
|
||||
process.on('unhandledRejection', common.mustNotCall());
|
||||
process.on('uncaughtException', uncaughtException);
|
||||
|
||||
const eventTarget = new EventTarget();
|
||||
|
||||
|
||||
@ -55,15 +55,15 @@ process.on(
|
||||
process.on('uncaughtException', common.mustCall((err, origin) => {
|
||||
assert.strictEqual(origin, 'uncaughtException');
|
||||
assert.strictEqual(err, theErr);
|
||||
}));
|
||||
|
||||
process.nextTick(common.mustCall(() => {
|
||||
// Test with uncaughtExceptionCaptureCallback installed
|
||||
process.setUncaughtExceptionCaptureCallback(common.mustCall(
|
||||
(err) => assert.strictEqual(err, theErr))
|
||||
);
|
||||
process.nextTick(common.mustCall(() => {
|
||||
// Test with uncaughtExceptionCaptureCallback installed
|
||||
process.setUncaughtExceptionCaptureCallback(common.mustCall(
|
||||
(err) => assert.strictEqual(err, theErr))
|
||||
);
|
||||
|
||||
throw theErr;
|
||||
throw theErr;
|
||||
}));
|
||||
}));
|
||||
|
||||
throw theErr;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user