Live data from Hacker News

Node.js error handling

snmaynard.com

11–20 of 24 posts

Re: Node.js error handling

#11
post #5

Unfortunately error handling in Node.js is a total mess. As with most new technologies there are few standards and whatever standards there are are subject to change. It was only a short time ago that many Node.js libs were being produced with promises. The most common style I see today is this callback style: doAsyncCall(function(err, result){ if(err){ // handle err } }); Unfortunately this is prone to error. When w…

with (er, result) -> you may find yourself polling both er and result.status

in practice I find I this means relatively ugly or unhelpful error messages through the first parameter are successively refined by conditionally setting helpful status and message attributes on the second

this style is kinda consistent with ajax calls on the client that may either fail, or return data containing an error.

Re: Node.js error handling

#12
I actually just wrote a Node + Express + Backbone error handling system today.

I've been staying sane through the use of the 'Q' promise package (https://github.com/kriskowal/q). For example, in the below code chunk any errors thrown in makeEmailConfirmation or sendEmailConfirmation will land in the .fail() catch block.

I believe using a promise system is the only way to avoid callback hell.

  var deferred = Q.defer();

  ...  
  
  Storage.CustomLinks.makeEmailConfirmationLink(user)
  .then(function(link) {
    return Email.sendEmailConfirmation(user, link);
  })
  .then(function(result) {
    deferred.resolve(result);
  })
  .fail(function(err) {
    deferred.reject(new ServerError(err));
  })
  .end();

  ...

  return deferred.promise;

Re: Node.js error handling

#13
post #5

Unfortunately error handling in Node.js is a total mess. As with most new technologies there are few standards and whatever standards there are are subject to change. It was only a short time ago that many Node.js libs were being produced with promises. The most common style I see today is this callback style: doAsyncCall(function(err, result){ if(err){ // handle err } }); Unfortunately this is prone to error. When w…

Is this really the most common style? It seems to me that this is more common:

  doAsyncCall(function onSuccess(result) {
    // do things
  }, function onError(err) {
    // No need to check, it's really an error.
  });
This is much cleaner and lets you reuse error handling functions.

Re: Node.js error handling

#15
post #12

I actually just wrote a Node + Express + Backbone error handling system today. I've been staying sane through the use of the 'Q' promise package ( https://github.com/kriskowal/q ). For example, in the below code chunk any errors thrown in makeEmailConfirmation or sendEmailConfirmation will land in the .fail() catch block. I believe using a promise system is the only way to avoid callback hell. var deferred = Q.defer(…

I've recently written an application extensively using Q, and was very pleased at how clean my code ended up being. Particularly in comparison to how node.js code tends to end up looking once your callback pyramids start to grow.

Re: Node.js error handling

#16
post #5

Unfortunately error handling in Node.js is a total mess. As with most new technologies there are few standards and whatever standards there are are subject to change. It was only a short time ago that many Node.js libs were being produced with promises. The most common style I see today is this callback style: doAsyncCall(function(err, result){ if(err){ // handle err } }); Unfortunately this is prone to error. When w…

Is this really the most common style? It seems to me that this is more common: doAsyncCall(function onSuccess(result) { // do things }, function onError(err) { // No need to check, it's really an error. }); This is much cleaner and lets you reuse error handling functions.

What a great pattern! I have to disagree though, (err, data) seems much more popular. Until now I'd never seen this (fantastic) style.

Re: Node.js error handling

#17

Earlier quoted context omitted.

Is this really the most common style? It seems to me that this is more common: doAsyncCall(function onSuccess(result) { // do things }, function onError(err) { // No need to check, it's really an error. }); This is much cleaner and lets you reuse error handling functions.

What a great pattern! I have to disagree though, (err, data) seems much more popular. Until now I'd never seen this (fantastic) style.

I don't think that this style is fantastic. This means that the pair of success/error callbacks is not reified, so there isn't a single object to pass around or manipulate. The result is that composition is harder. In order to create higher order asynchronous operations, like those in Async.js [1], you need to either pass two arguments or use an array or object to pair the error handlers together. This is particularly important if you want to return a pair of handlers from a function.

In the two-callback model, the most common way to reify the handler pair is with a {success:...,error:...} object. This is much better than function(x,y,z,success,error), but still has the problem that you now need to override two handlers if you want to wrap some completion logic, regardless of success/failure. For example, if you want to close a file handle, win or lose, you need to provide two new functions.

Composition greatly benefits from a singular object. The Node.js approach is the (err,data) callback. It's an extremely simple and successful approach. The other approach are promises/futures, which internally can be implemented with one or more callbacks, but provide a nice clean interface for composition. You could get that with success/error objects, but you're exposing the internals rather than an interface, like you should be doing. A good promise interface would let you choose an implementation without tying you to any particular callback model.

[1] https://github.com/caolan/async

Re: Node.js error handling

#18
post #5

Unfortunately error handling in Node.js is a total mess. As with most new technologies there are few standards and whatever standards there are are subject to change. It was only a short time ago that many Node.js libs were being produced with promises. The most common style I see today is this callback style: doAsyncCall(function(err, result){ if(err){ // handle err } }); Unfortunately this is prone to error. When w…

That way is longer without reason, you must first define in the function scope both variables error and result; the latter only receives assignation when no error has been generated.

    function doAsyncCall(callback){
        var error, result;
        // .. do some async stuff
        // assign error if there was one or result when everything went fine
        if( !error ){ result = data; }
        callback(error, result);
    }

Re: Node.js error handling

#20
post #5

Unfortunately error handling in Node.js is a total mess. As with most new technologies there are few standards and whatever standards there are are subject to change. It was only a short time ago that many Node.js libs were being produced with promises. The most common style I see today is this callback style: doAsyncCall(function(err, result){ if(err){ // handle err } }); Unfortunately this is prone to error. When w…

Is this really the most common style? It seems to me that this is more common: doAsyncCall(function onSuccess(result) { // do things }, function onError(err) { // No need to check, it's really an error. }); This is much cleaner and lets you reuse error handling functions.

My experience of the f(onerror, onsuccess) pattern is that it does not scale well when multiple functions are nested, as the error-handling code gets pushed further and further down the page from the actual error site it handles.
Post reply on HN