process: ignore asyncId 0 in exception handler

Today, the global uncaught exception handler is the only
place where asyncId 0 is not ignored and we still proceed
to call emitAfter. This would've already failed one of
our correctness tests in async_hooks if not for some other
code meant to handle a different edge case.

Fixes: https://github.com/nodejs/node/issues/22982

PR-URL: https://github.com/nodejs/node/pull/41424
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Anatoli Papirovski 2022-01-06 22:04:30 -08:00 committed by Gerhard Stöbich
parent 81e88f27b7
commit 51783320a4
3 changed files with 24 additions and 5 deletions

View File

@ -20,7 +20,8 @@ const {
clearAsyncIdStack,
hasAsyncIdStack,
afterHooksExist,
emitAfter
emitAfter,
popAsyncContext,
} = require('internal/async_hooks');
// shouldAbortOnUncaughtToggle is a typed array for faster
@ -183,7 +184,11 @@ function createOnGlobalUncaughtException() {
// Emit the after() hooks now that the exception has been handled.
if (afterHooksExist()) {
do {
emitAfter(executionAsyncId());
const asyncId = executionAsyncId();
if (asyncId === 0)
popAsyncContext(0);
else
emitAfter(asyncId);
} while (hasAsyncIdStack());
}
// And completely empty the id stack, including anything that may be

View File

@ -168,9 +168,6 @@ class ActivityCollector {
}
const err = new Error(`Found a handle whose ${hook}` +
' hook was invoked but not its init hook');
// Don't throw if we see invocations due to an assertion in a test
// failing since we want to list the assertion failure instead
if (/process\._fatalException/.test(err.stack)) return null;
throw err;
}
return h;

View File

@ -0,0 +1,17 @@
'use strict';
const common = require('../common');
const initHooks = require('./init-hooks');
const hooks = initHooks();
hooks.enable();
setImmediate(() => {
throw new Error();
});
setTimeout(() => {
throw new Error();
}, 1);
process.on('uncaughtException', common.mustCall(2));