Note: I already found a solution to this problem, posting it here for posterity. See the selected answer.
The following (simplified) code throws an uncatchable "write EPIPE" (and in some scenarios "write EOF") error:
const { exec } = require("child_process");
const veryLargeString = "x".repeat(10 * 1024 * 1024);
const p = exec("gibberishThatWillFailImmediately");
p.stdin.write(veryLargeString);
My failed attempts at the problem:
- Checking the
stdin.destroyed
flag before writing - Checking the
stdin.writeableEnded
flag before writing - Chunking the input and checking
stdin.writeableEnded
before each chunk. This one lead to undeterministic behavior. - Wrapping the
stdin.write(data)
line with try-catch - Calling
stdin.end(data)
instead ofstdin.write(data)
- Pass
stdin.write()
a callback that should get any error that occurs. The callback got the error, but didn't prevent it from being thrown.
Registering an 'error' handler to the
stdin
stream seems to prevent the error from being thrown. Like this:Here's an example that returns a promise containing the error or null if no error occured: