From 48e94b2e386641044989ef2dfe98b0d30ae09b20 Mon Sep 17 00:00:00 2001 From: Rahulstark2 Date: Sat, 3 Oct 2026 22:47:44 +0530 Subject: [PATCH] fix(sdk): preserve child exit status over EPIPE --- packages/sdk/src/named-gate-lowering.ts | 5 ++++- packages/sdk/tests/named-gate-diagnostics.test.ts | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/sdk/src/named-gate-lowering.ts b/packages/sdk/src/named-gate-lowering.ts index 8a4ac5039..ed7f6f39b 100644 --- a/packages/sdk/src/named-gate-lowering.ts +++ b/packages/sdk/src/named-gate-lowering.ts @@ -128,9 +128,12 @@ process.exit(result.status===0?0:1);`; body = `const result=cp.spawnSync('wc',['-w'],{input:text,encoding:'utf8',env:{...process.env,LC_ALL:'C'}}); const noise=(result.stderr||'').trim().slice(-200); const said=noise===''?'':': '+noise; -if(result.error)fail('could not run wc -w: '+(result.error.code||result.error.message)+said); if(result.signal)fail('wc -w was terminated by '+result.signal+said); +if(result.status!==null){ if(result.status!==0)fail('wc -w exited '+result.status+said); +}else if(result.error){ +fail('could not run wc -w: '+(result.error.code||result.error.message)+said); +} const count=result.stdout.trim(); if(!/^[0-9]+$/.test(count))fail('wc -w printed '+JSON.stringify(count.slice(0,80))+' instead of a word count'+said); process.stdout.write(BigInt(count).toString());`; diff --git a/packages/sdk/tests/named-gate-diagnostics.test.ts b/packages/sdk/tests/named-gate-diagnostics.test.ts index b35c60eb2..48edc5ceb 100644 --- a/packages/sdk/tests/named-gate-diagnostics.test.ts +++ b/packages/sdk/tests/named-gate-diagnostics.test.ts @@ -279,4 +279,19 @@ describe('word_count_bounds reports why its own child failed', () => { expect(capture.status).toBe(1); expect(capture.stderr).toContain('SIGKILL'); }); + + it('does not report EPIPE when wc exits nonzero after closing stdin', () => { + const path = stubWordCount('exit 2'); + const largeInput = 'x'.repeat(100_000); + + const capture = runGate( + command(), + { output: deterministicEnvelope(largeInput) }, + { path }, + ); + + expect(capture.status).toBe(1); + expect(capture.stderr).toContain('exited 2'); + expect(capture.stderr).not.toContain('EPIPE'); + }); });