mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 00:03:52 +00:00
fix(process): stop a stream error from crashing the main process
Same class as the stdin EPIPE finding, two instances further on: stdout and stderr had data listeners and no error listeners, and an unhandled error on a stream is an uncaught exception. Scoped to runProcess, which owns the child outright. spawnProcess hands the streams to its caller, and a blanket handler there defeats callers that track and remove their own listeners -- the SSH ProxyCommand transport does exactly that, and its cleanup test caught the attempt. Documented on spawnProcess so the boundary is explicit rather than inferred.
This commit is contained in:
@@ -191,8 +191,10 @@ describe('wedge cooldown', () => {
|
||||
await vi.advanceTimersByTimeAsync(10_000)
|
||||
|
||||
// The recovered reader must answer, not report a wedge left by a dead timer.
|
||||
getAllProcesses.mockImplementation((cb: (rows: unknown) => void) => cb(NATIVE))
|
||||
resetWindowsProcessTableForTests()
|
||||
__setWindowsProcessTreeLoaderForTests(() => ({
|
||||
ProcessDataFlag: { None: 0, Memory: 1, CommandLine: 2 },
|
||||
getAllProcesses: (cb: (rows: typeof NATIVE | undefined) => void) => cb(NATIVE)
|
||||
}))
|
||||
await expect(readWindowsProcessTableFresh()).resolves.toHaveLength(NATIVE.length)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -248,13 +248,6 @@ export function runProcess(spec: ProcessSpec): Promise<ProcessResult> {
|
||||
// Why close rather than leave open: a child that reads stdin (a hook
|
||||
// draining its payload, a CLI probing for a TTY) otherwise blocks until the
|
||||
// timeout instead of seeing EOF immediately.
|
||||
// Why an error listener and not just end(): a child that exits without
|
||||
// reading makes the queued write fail with EPIPE, and an unhandled error on
|
||||
// a stream is an uncaught exception -- which takes the whole main process
|
||||
// down. The child's own error listener does not cover this stream. The
|
||||
// exit code already carries the outcome, so failing to deliver stdin is
|
||||
// not separately interesting.
|
||||
child.stdin?.on('error', () => {})
|
||||
child.stdin?.end(spec.input)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user