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.destroyedflag before writing - Checking the
stdin.writeableEndedflag before writing - Chunking the input and checking
stdin.writeableEndedbefore 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
stdinstream 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: