Skip to main content
Ben Nadel at InVision In Real Life (IRL) 2019 (Phoenix, AZ) with: Lisa Tierney
Ben Nadel at InVision In Real Life (IRL) 2019 (Phoenix, AZ) with: Lisa Tierney

Node.js Streams Inherit Error-Handling Behavior From EventEmitter

By
Published in

I started digging into Node.js recently as a means to understand why my Gulp.js build script wasn't working. This lead me down a rabbit hole of exploration into Streams in Node.js and, more specifically, into how streams handle errors. And, while this may be obvious to most Node.js developers, it took me a good while to figure out: Streams don't really do any error handling; they inherit error handling behavior from EventEmitter.

Ok, that last statement isn't entirely true - Node.js Streams do handle some errors around .pipe() and around how connections get cleaned up; but, they don't suppress errors. This means that an error emitted by a Stream will turn into an exception unless there is at least one externally-bound "error" event handler. This last caveat is really the point of this blog post.

Other than looking in the code, the evidence of this can be seen in the stack trace of uncaught exceptions. First, let's look at emitting an error in an instance of EventEmitter:

var events = require( "events" );

var badEventer = new events.EventEmitter();

badEventer.emit( "error", new Error( "Something went wrong." ) );

When we run this EventEmitter code, we get the following terminal output:

events.js:72
throw er; // Unhandled 'error' event

As you can see, the emitted event is being thrown() in the events.js module, line 72.

Ok, now let's look at emitting an error event in an instance of Readable stream:

var stream = require( "stream" );

var badStream = new stream.Readable();

badStream.emit( "error", new Error( "Something went wrong." ) );

When we run this Readable steam code, we get the following terminal output:

events.js:72
throw er; // Unhandled 'error' event

As you can see, it's the same exact error. This is because Node.js Streams are EventEmitters in that they [Streams] have the EventEmitter class in their prototype chain and use the EventEmitter as a super constructor.

Ok, so I know this blog post is super basic and you probably think this is like Node.js 101; but, building a solid mental model of Node.js streams has been a really challenging (yet awesome) adventure for me. I still haven't debugged my Gulp.js problem; but, I think I'm getting really close to understanding what is going wrong.

Want to use code from this post? Check out the license.

Reader Comments

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel