This is all really good info and I'm not gonna argue. I still think it'd be
nice if there was a nicer shorthand to tell one emitter to forward certain
events to another emitter. So at least it's less of a pain to do it
manually. I kinda don't think there is a good shorthand though. Even adding
it to the options hash every time isn't much less onerous than just doing
multiple on('error', ...).:Marco PS - I'm purposely not commenting on the example using domains. I don't have anything constructive to say. On Thu, Nov 29, 2012 at 8:52 AM, Isaac Schlueter <[email protected]> wrote: > The biggest problem with forwarding errors happens when you have > duplex streams that forward to one another, and as Martin points out, > streams that emit errors in different circumstances. > > For example, let's say that you added something like this in the > pipe() function: > > src.on('error', function(er) { > dest.emit('error', er); > }); > > What happens when you do this? > > // encryptor service > net.createServer(function (socket) { > socket.pipe(new Encryptor()).pipe(socket); > }); > > If the socket emits error, it forwards to the encryptor, which > forwards it to the socket, and it's an infinite loop. Now every > encryption error is also a RangeError! > > You *could* make this work by keeping track of whether a stream's > error events are already forwarded, but that's just more state > tracking and complexity, and it ends up being somewhat > indeterministic. For example, these two servers would be > error-forwarded differently, though they should be semantically > equivalent: > > net.createServer(function (socket) { > // all errors emit on socket > var e = new Encryptor(); > e.pipe(socket).pipe(e); > }); > > net.createServer(function (socket) { > // all errors emit on encryptor > var e = new Encryptor(); > socket.pipe(e).pipe(socket); > }); > > > > To Martin's point, this also obscures the source of the error. Though > it's more verbose, stuff like this is actually quite important: > > fs.createReadStream(tarball) > .on('error', handleFileReadError) > .pipe(gzip.Gunzip()) > .on('error', handleUnzipError) > .pipe(tar.Extract({ path: targetPath })) > .on('error', handleTarExtractError) > .on('close', cb) > > All those different errors have different information, metadata, etc., > and in many cases, if you don't know the object that emitted them, > then you don't have a lot of insight into what error message you > should print out. ("Your program says 'illegal data', what's going > wrong?" Good luck debugging that!) > > > The moral of the story is that you must either attach error listeners > to all streams you touch, or accept that they will throw (and perhaps > gather all throws into a domain). For example, if you really *wanted* > to only have a single error handler you could do this: > > var d = domain.create(); > d.on('error', handleAllErrors); > d.run(function() { > fs.createReadStream(tarball) > .pipe(gzip.Gunzip()) > .pipe(tar.Extract({ path: targetPath })) > .on('close', cb); > }); > > This is actually not so bad. Domains add a bit of metadata to the > error object, so it's not too hard to figure out whether it was an > "organic" throw, or an error event that was emitted by some object. > > > > On Wed, Nov 28, 2012 at 9:54 PM, Martin Cooper <[email protected]> > wrote: > > > > > > On Wed, Nov 28, 2012 at 2:05 PM, Jeff Barczewski < > [email protected]> > > wrote: > >> > >> Agreed. Especially if the error happens after the initial connection > >> (which is probably when most would occur), then it won't be caught by > any > >> try/catch so it would have to rely on domains. > >> > >> If you have setup an error handler then it is just nice to deal with it > >> there in one spot. > > > > > > That depends on what you're going to do with it. As a simple example, if > I > > create a read stream on a tarball, pipe it through Gunzip, and pipe that > > through Untar, I may well be interested in reporting to the user which > one > > of those things messed up if something went wrong. What I *don't* want to > > have to do is muddle through inconsistently constructed Error objects to > try > > to figure that out for myself, if there's only one place to put my error > > handler. > > > > In other words, I *like* the fact that the error handlers are > interspersed > > within my pipe setup, because it gives me flexibility in both > determining, > > and reporting, what went wrong. If I don't want to make use of that > > flexibility, then I can reuse the same handler, as in your example. But I > > have that choice. > > > > -- > > Martin Cooper > > > >> -- > >> Job Board: http://jobs.nodejs.org/ > >> Posting guidelines: > >> https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > >> You received this message because you are subscribed to the Google > >> Groups "nodejs" group. > >> To post to this group, send email to [email protected] > >> To unsubscribe from this group, send email to > >> [email protected] > >> For more options, visit this group at > >> http://groups.google.com/group/nodejs?hl=en?hl=en > > > > > > -- > > Job Board: http://jobs.nodejs.org/ > > Posting guidelines: > > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > > You received this message because you are subscribed to the Google > > Groups "nodejs" group. > > To post to this group, send email to [email protected] > > To unsubscribe from this group, send email to > > [email protected] > > For more options, visit this group at > > http://groups.google.com/group/nodejs?hl=en?hl=en > > -- > Job Board: http://jobs.nodejs.org/ > Posting guidelines: > https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines > You received this message because you are subscribed to the Google > Groups "nodejs" group. > To post to this group, send email to [email protected] > To unsubscribe from this group, send email to > [email protected] > For more options, visit this group at > http://groups.google.com/group/nodejs?hl=en?hl=en > -- Marco Rogers [email protected] | https://twitter.com/polotek Life is ten percent what happens to you and ninety percent how you respond to it. - Lou Holtz -- Job Board: http://jobs.nodejs.org/ Posting guidelines: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines You received this message because you are subscribed to the Google Groups "nodejs" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/nodejs?hl=en?hl=en
