()
| 60 | let abortKillTimeout: NodeJS.Timeout | null = null; |
| 61 | |
| 62 | const abortHandler = () => { |
| 63 | if (abortKillTimeout) { |
| 64 | return; |
| 65 | } |
| 66 | // First, try graceful termination of entire process tree |
| 67 | if (child.exitCode === null && !child.killed) { |
| 68 | logDebug(`Abort signal received, killing process tree (pid=${child.pid}) with SIGTERM`); |
| 69 | // Note: We don't await here because we're in a sync callback, |
| 70 | // but killProcessByChildProcess now waits for processes to die internally |
| 71 | void killProcessByChildProcess(child, false); |
| 72 | } |
| 73 | // Set timeout for forceful kill if graceful doesn't work |
| 74 | abortKillTimeout = setTimeout(() => { |
| 75 | if (child.exitCode === null && !child.killed) { |
| 76 | logDebug('Abort timeout reached, sending SIGKILL'); |
| 77 | try { |
| 78 | void killProcessByChildProcess(child, true); |
| 79 | } catch (error) { |
| 80 | logDebug('Failed to send SIGKILL', error); |
| 81 | } |
| 82 | } |
| 83 | }, abortKillTimeoutMs); |
| 84 | }; |
| 85 | |
| 86 | if (options.signal.aborted) { |
| 87 | abortHandler(); |
no test coverage detected