mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
docs(bash-local): clarify the stdin error handler swallows ANY write error, not just EPIPE
Review noted the handler's comment said "EPIPE" while the code swallowed every stdin 'error'. Swallowing any stdin-write error IS correct here — the write is best-effort and the command's authoritative outcome is its exit code + captured output (reported by the `close` handler regardless of whether the write landed). A rare non-EPIPE pipe fault means the command ran with incomplete stdin, which it surfaces itself via its own exit/output; rejecting `done` would instead discard that real output and turn it into an opaque infrastructure error. Widen the comment to state this rather than implying only EPIPE is caught. No behavior change.
This commit is contained in:
@@ -308,12 +308,6 @@ export function runBash(spec: SpawnSpec, internals: RunInternals = {}): RunningB
|
||||
detached: true,
|
||||
})
|
||||
|
||||
// A child that exits without reading stdin makes the write error EPIPE —
|
||||
// swallow it (the command's outcome rides on its exit code/output, not the
|
||||
// stdin write) so it never crashes the host or rejects `done`.
|
||||
child.stdin.on('error', () => { /* EPIPE: child closed stdin early; outcome rides on exit. */ })
|
||||
child.stdin.end(spec.stdin ?? '')
|
||||
|
||||
const stdout = new OutputCollector(spec.maxOutputBytes, 'stdout', spillDir)
|
||||
const stderr = new OutputCollector(spec.maxOutputBytes, 'stderr', spillDir)
|
||||
child.stdout.on('data', (chunk: Buffer) => { stdout.push(chunk) })
|
||||
@@ -347,6 +341,20 @@ export function runBash(spec: SpawnSpec, internals: RunInternals = {}): RunningB
|
||||
}
|
||||
spec.signal?.addEventListener('abort', onAbort, { once: true })
|
||||
|
||||
// Write stdin and close it. This handler must exist: an unhandled 'error' on
|
||||
// the stream would throw and crash the host. We swallow the error rather than
|
||||
// reject `done`, and that is correct for ANY stdin-write error, not just the
|
||||
// common one — the stdin write is BEST-EFFORT, while the command's authoritative
|
||||
// outcome is its exit code + captured output, which the `close` handler reports
|
||||
// regardless of whether the write landed. The expected case is EPIPE (the child
|
||||
// exited without reading, so closing our end of a still-full pipe fails); a rare
|
||||
// non-EPIPE pipe fault means the command ran with incomplete stdin, and it
|
||||
// surfaces that itself through its own exit/output (e.g. a hook that gets
|
||||
// truncated JSON errors out) — rejecting here would instead discard that real
|
||||
// output and turn it into an opaque infrastructure error, which is worse.
|
||||
child.stdin.on('error', () => { /* stdin write is best-effort; outcome rides on exit/output. */ })
|
||||
child.stdin.end(spec.stdin ?? '')
|
||||
|
||||
const done = new Promise<SpawnOutcome>((resolve, reject) => {
|
||||
child.on('error', (error) => {
|
||||
// Spawn-level failure (ENOENT cwd, EACCES, …): no close event with
|
||||
|
||||
Reference in New Issue
Block a user