« JSCoverage Report for Jasmine | Main | Jeremy Fink and the Meaning of Life »

Underscore Mixin for Error Handling

A common pattern that pops up in my node.js programming is this:

// callback is defined elsewhere
object.someAsyncFunction(param1, function(err, response) {
    if (err) {
        return callback(err);
    }
    // do something with response
    callback(undefined, transformedResponse);
});

When I'm really paranoid about ensuring the callback is called I wrap the code in a try/catch:

// callback is defined elsewhere
object.someAsyncFunction(param1, function(err, response) {
    if (err) {
        return callback(err);
    }
    try {
        // do something with response
        callback(undefined, transformedResponse);
    } catch(err) {
        callback(err);
    }
});

Talk about a lot of boilerplate code. Since I use underscore heavily throughout my code I created the following mixin:

_.mixin({
    errTryWrap: function(fn, callback, context) {
        return function() {
            // check for err
            if (arguments[0]) {
                return callback(arguments[0]);
            }
            try {
                // strip the err from the arguments passed down
                return fn.apply(context, _.rest(arguments));
            } catch(err) {
                callback(err);
            }
        };
    }
});

With that in place the paranoid version now becomes:

// callback is defined elsewhere
object.someAsyncFunction(param1, _.errTryWrap(function(response) {
    // do something with response
    callback(undefined, transformedResponse);
}, callback));

Much cleaner. I'm not crazy about the name of the mixin but it makes it easy to find in the code should I come up with a better name later.

Tags: nodejs

Comments

The new domain feature in another way of reducing this boilerplate code. See http://nodejs.org/docs/latest/api/domain.html