When something fails in the middle of a stream pipeline, how does that error actually travel?
A strong answer can say at the mechanism level what pipe fails to clean up, which stream survives and what leaks, and reaches for pipeline with abort semantics
So streams report their failures through 'error' events, and the thing that trips people up is that .pipe() doesn't forward those errors. An error on one stream in the chain never reaches the others, so with a.pipe(b).pipe(c) I'd need an error listener on all three streams, which is easy to forget. Modern code uses stream.pipeline instead. It wires the stages together, forwards any error to a single callback, and cleans up every stream when something fails. There's also a promise-based version in stream/promises that works well with async/await. The rule I go by is pretty simple. .pipe() is fine for quick scripts, but production code should use pipeline, so a failure in any stage tears the whole chain down and hands me one error to handle.