Skip to content

Commit b478e4e

Browse files
committed
fix: handle EIO stream errors gracefully in bin.ts
The stream error handler in bin.ts only handled EPIPE (broken pipe) and re-threw all other errors. When stdout/stderr emits an EIO error event (non-recoverable I/O failure on the stream fd), the throw inside the synchronous event handler becomes an uncaught exception — matching the auto.node.onuncaughtexception mechanism seen in CLI-H2. EIO is a POSIX errno for low-level I/O failures (terminal device driver error, broken PTY, disk I/O failure on redirected output). Like EPIPE, the stream is unusable and the CLI should exit cleanly. Fixes CLI-H2
1 parent 70694da commit b478e4e

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

src/bin.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66
* the full CLI with telemetry, middleware, and error recovery.
77
*/
88

9-
// Exit cleanly when downstream pipe consumer closes (e.g., `sentry issue list | head`).
10-
// EPIPE (errno -32) is normal Unix behavior — not an error. Node.js/Bun ignore SIGPIPE
11-
// at the process level, so pipe write failures surface as async 'error' events on the
12-
// stream. Without this handler they become uncaught exceptions.
9+
// Exit cleanly on non-recoverable stream I/O errors.
10+
// - EPIPE (errno -32): downstream pipe consumer closed (e.g., `sentry issue list | head`).
11+
// Normal Unix behavior — not an error. Node.js/Bun ignore SIGPIPE at the process level,
12+
// so pipe write failures surface as async 'error' events on the stream.
13+
// - EIO (errno -5): low-level I/O failure on the stream fd (e.g., terminal device driver
14+
// error, broken PTY, disk I/O failure on redirected output). Non-recoverable — the
15+
// stream is unusable. Seen in CLI-H2 on self-hosted macOS with virtualized storage.
16+
// Without this handler these errors become uncaught exceptions.
1317
function handleStreamError(err: NodeJS.ErrnoException): void {
14-
if (err.code === "EPIPE") {
18+
if (err.code === "EPIPE" || err.code === "EIO") {
1519
process.exit(0);
1620
}
1721
throw err;

0 commit comments

Comments
 (0)