mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 10:15:07 +08:00
child_process: clear timeout timer on spawn-time error too
When spawn() fails at the OS level (ENOENT, EACCES, EAGAIN, EMFILE, ENFILE), the resulting ChildProcess only ever emits 'error', never 'exit'. The `timeout` option's cleanup only listened for 'exit', so the timer stayed armed for the full `timeout` duration on any spawn-time failure, holding the event loop open well after the promise/callback had already settled via 'error'. Clear the timer on 'error' as well as 'exit'. Fixes: https://github.com/nodejs/node/issues/65504 Signed-off-by: kishore280 <maheshwarankishore@gmail.com> PR-URL: https://github.com/nodejs/node/pull/65506 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Stefan Stojanovic <stefan.stojanovic@janeasystems.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
This commit is contained in:
1 parent
b7406b0a9b
commit
c4381765fe
2 files changed
+21
-1
No files matched your search
@@ -824,7 +824,8 @@ function spawn(file, args, options) {
|
||||
}
|
||||
}, options.timeout);
|
||||
|
||||
child.once('exit', () => {
|
||||
// 'close' always fires after 'exit', or after 'error' on a spawn failure.
|
||||
child.once('close', () => {
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = null;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
// Measures the child's actual exit time, not just its 'error' event.
|
||||
// The outer spawnSync timeout catches a leaked inner timer.
|
||||
|
||||
const common = require('../common');
|
||||
const { spawnSyncAndExitWithoutError } = require('../common/child_process');
|
||||
|
||||
const bugStallMs = common.platformTimeout(10000);
|
||||
const outerTimeoutMs = common.platformTimeout(2000);
|
||||
|
||||
spawnSyncAndExitWithoutError(process.execPath, ['-e', `
|
||||
const { spawn } = require('child_process');
|
||||
const cp = spawn(process.execPath, ['--version'], {
|
||||
cwd: '/nonexistent/path/that/should/never/exist',
|
||||
timeout: ${bugStallMs},
|
||||
});
|
||||
cp.on('error', () => {});
|
||||
`], { timeout: outerTimeoutMs });
|
||||
Reference in new issue
Block a user