diff --git a/src/js/node/child_process.ts b/src/js/node/child_process.ts index 0a09cff0e5..8e4197b0ef 100644 --- a/src/js/node/child_process.ts +++ b/src/js/node/child_process.ts @@ -456,14 +456,11 @@ function exec(command, options, callback) { return execFile(opts.file, opts.options, opts.callback); } +const kCustomPromisifySymbol = Symbol.for("nodejs.util.promisify.custom"); + const customPromiseExecFunction = orig => { return (...args) => { - let resolve; - let reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); + const { resolve, reject, promise } = Promise.withResolvers(); promise.child = orig(...args, (err, stdout, stderr) => { if (err !== null) { @@ -479,12 +476,22 @@ const customPromiseExecFunction = orig => { }; }; -Object.defineProperty(exec, Symbol.for("nodejs.util.promisify.custom"), { +Object.defineProperty(exec, kCustomPromisifySymbol, { __proto__: null, configurable: true, value: customPromiseExecFunction(exec), }); +exec[kCustomPromisifySymbol][kCustomPromisifySymbol] = exec[kCustomPromisifySymbol]; + +Object.defineProperty(execFile, kCustomPromisifySymbol, { + __proto__: null, + configurable: true, + value: customPromiseExecFunction(execFile), +}); + +execFile[kCustomPromisifySymbol][kCustomPromisifySymbol] = execFile[kCustomPromisifySymbol]; + /** * Spawns a new process synchronously using the given `file`. * @param {string} file diff --git a/test/regression/issue/10170.test.ts b/test/regression/issue/10170.test.ts new file mode 100644 index 0000000000..b58fed5977 --- /dev/null +++ b/test/regression/issue/10170.test.ts @@ -0,0 +1,11 @@ +import { test, expect } from "bun:test"; +import { bunExe } from "harness"; +import { execFile } from "node:child_process"; +import util from "node:util"; + +test("issue 10170", async () => { + const execFileAsync = util.promisify(execFile); + const result = await execFileAsync(bunExe(), ["--version"]); + expect(result.stdout).toContain(Bun.version); + expect(result.stderr).toBe(""); +});