async_hooks: enable AsyncLocalStorage once constructed

This fixes the leak behavior when using `enterWith` when no
`AsyncLocalStorage`s were enabled inside a promise.

PR-URL: https://github.com/nodejs/node/pull/58029
Fixes: https://github.com/nodejs/node/issues/53037
Refs: https://github.com/nodejs/node/pull/58019
Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
Chengzhong Wu 2025-04-27 23:43:28 +02:00 committed by GitHub
parent c712dd284b
commit 8e7ae60e3b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 39 additions and 0 deletions

View File

@ -51,6 +51,8 @@ class AsyncLocalStorage {
if (options.name !== undefined) {
this.#name = `${options.name}`;
}
this._enable();
}
/** @type {string} */

View File

@ -0,0 +1,37 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { AsyncLocalStorage } = require('async_hooks');
// Verify that `enterWith()` does not leak the store to the parent context in a promise.
const als = new AsyncLocalStorage();
async function asyncFunctionAfterAwait() {
await 0;
als.enterWith('after await');
}
function promiseThen() {
return Promise.resolve()
.then(() => {
als.enterWith('inside then');
});
}
async function asyncFunctionBeforeAwait() {
als.enterWith('before await');
await 0;
}
async function main() {
await asyncFunctionAfterAwait();
await promiseThen();
assert.strictEqual(als.getStore(), undefined);
// This is a known limitation of the `enterWith` API.
await asyncFunctionBeforeAwait();
assert.strictEqual(als.getStore(), 'before await');
}
main().then(common.mustCall());