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

Reply via email to