mirror of
https://github.com/nodejs/node.git
synced 2025-05-22 05:46:19 +00:00

Until now, the async_hooks PromiseHook did not register the Promise’s async id and trigger id on the id stack, so inside the `.then()` handler those ids would be invalid. To fix this, add push and pop calls to its `before` and `after` parts, respectively. Some care needs to be taken for the cases that the Promise hook is being disabled or enabled during the execution of a Promise handler; in the former case, actually removing the hook is delayed by adding another task to the microtask queue, in the latter case popping the id off the async id stack is skipped if the ids don’t match. Fixes: https://github.com/nodejs/node/issues/13583 PR-URL: https://github.com/nodejs/node/pull/13585 Reviewed-By: Trevor Norris <trevnorris@gmail.com>
48 lines
1.3 KiB
JavaScript
48 lines
1.3 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../../common');
|
|
const assert = require('assert');
|
|
const async_hooks = require('async_hooks');
|
|
const binding = require(`./build/${common.buildType}/binding`);
|
|
|
|
// Baseline to make sure the internal field isn't being set.
|
|
assert.strictEqual(
|
|
binding.getPromiseField(Promise.resolve(1)),
|
|
0,
|
|
'Promise internal field used despite missing enabled AsyncHook');
|
|
|
|
const hook0 = async_hooks.createHook({}).enable();
|
|
|
|
// Check that no PromiseWrap is created when there are no hook callbacks.
|
|
assert.strictEqual(
|
|
binding.getPromiseField(Promise.resolve(1)),
|
|
0,
|
|
'Promise internal field used despite missing enabled AsyncHook');
|
|
|
|
hook0.disable();
|
|
|
|
let pwrap = null;
|
|
const hook1 = async_hooks.createHook({
|
|
init(id, type, tid, resource) {
|
|
pwrap = resource;
|
|
}
|
|
}).enable();
|
|
|
|
// Check that the internal field returns the same PromiseWrap passed to init().
|
|
assert.strictEqual(
|
|
binding.getPromiseField(Promise.resolve(1)),
|
|
pwrap,
|
|
'Unexpected PromiseWrap');
|
|
|
|
hook1.disable();
|
|
|
|
// Check that internal fields are no longer being set. This needs to be delayed
|
|
// a bit because the `disable()` call only schedules disabling the hook in a
|
|
// future microtask.
|
|
setImmediate(() => {
|
|
assert.strictEqual(
|
|
binding.getPromiseField(Promise.resolve(1)),
|
|
0,
|
|
'Promise internal field used despite missing enabled AsyncHook');
|
|
});
|