diff --git a/lib/child_process.js b/lib/child_process.js index b67ea1c7f05eca..daa1d44e8974df 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -368,6 +368,12 @@ function execFile(file /* , args, options, callback */) { } } + function abortHandler() { + if (!ex) + ex = new AbortError(); + process.nextTick(() => kill()); + } + if (options.timeout > 0) { timeoutId = setTimeout(function delayedKill() { kill(); @@ -376,14 +382,11 @@ function execFile(file /* , args, options, callback */) { } if (options.signal) { if (options.signal.aborted) { - process.nextTick(() => kill()); + process.nextTick(abortHandler); } else { const childController = new AbortController(); - options.signal.addEventListener('abort', () => { - if (!ex) - ex = new AbortError(); - kill(); - }, { signal: childController.signal }); + options.signal.addEventListener('abort', abortHandler, + { signal: childController.signal }); child.once('close', () => childController.abort()); } } diff --git a/test/parallel/test-child-process-execfile.js b/test/parallel/test-child-process-execfile.js index aec80b4e2baf22..49a4bdbda29957 100644 --- a/test/parallel/test-child-process-execfile.js +++ b/test/parallel/test-child-process-execfile.js @@ -53,12 +53,19 @@ const execOpts = { encoding: 'utf8', shell: true }; const ac = new AbortController(); const { signal } = ac; - const callback = common.mustCall((err) => { - assert.strictEqual(err.code, 'ABORT_ERR'); - assert.strictEqual(err.name, 'AbortError'); - }); - execFile(process.execPath, [echoFixture, 0], { signal }, callback); + const test = () => { + const check = common.mustCall((err) => { + assert.strictEqual(err.code, 'ABORT_ERR'); + assert.strictEqual(err.name, 'AbortError'); + assert.strictEqual(err.signal, undefined); + }); + execFile(process.execPath, [echoFixture, 0], { signal }, check); + }; + + test(); ac.abort(); + // Verify that it still works the same way now that the signal is aborted. + test(); } { diff --git a/test/parallel/test-child-process-spawn-controller.js b/test/parallel/test-child-process-spawn-controller.js index 399558569cc1ec..c25307907c1b26 100644 --- a/test/parallel/test-child-process-spawn-controller.js +++ b/test/parallel/test-child-process-spawn-controller.js @@ -4,18 +4,38 @@ const common = require('../common'); const assert = require('assert'); const cp = require('child_process'); -// Verify that passing an AbortSignal works -const controller = new AbortController(); -const { signal } = controller; +{ + // Verify that passing an AbortSignal works + const controller = new AbortController(); + const { signal } = controller; -const echo = cp.spawn('echo', ['fun'], { - encoding: 'utf8', - shell: true, - signal -}); + const echo = cp.spawn('echo', ['fun'], { + encoding: 'utf8', + shell: true, + signal + }); -echo.on('error', common.mustCall((e) => { - assert.strictEqual(e.name, 'AbortError'); -})); + echo.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + })); -controller.abort(); + controller.abort(); +} + +{ + // Verify that passing an already-aborted signal works. + const controller = new AbortController(); + const { signal } = controller; + + controller.abort(); + + const echo = cp.spawn('echo', ['fun'], { + encoding: 'utf8', + shell: true, + signal + }); + + echo.on('error', common.mustCall((e) => { + assert.strictEqual(e.name, 'AbortError'); + })); +}