April 17, 2013

Debugging Node.js Applications

Tonight I gave a talk at the Node.js in the wild meetup about Debugging Node.js Applications.

The slides are available at: https://life.neophi.com/danielr/files/DebuggingNodejsApplications.pdf

The sample code used is available at: https://github.com/NeoPhi/debugging

A video of the talk was made and is available at: http://www.youtube.com/watch?v=JNSy1roM82k

Thank you to all that came and the discussion we had.

Tags: nodejs talks

January 21, 2013

Annotated JSHint Configuration File

I've put together an annotated JSHint configuration file. This is mostly just a text formatted cut and paste of the documentation on the website (DRY shudder) in a format suitable for use with node-jshint. I find it handy to have it all in one place when setting up new node projects. You can grab the config from:

https://github.com/NeoPhi/jshint-config/

Tags: javascript jshint nodejs

September 30, 2012

Sharing Code Between Node.js Applications

Last night my colleague Tim Walling and I gave a a talk the Node.js in the wild Meetup on Sharing Code Between Node.js Applications. This was based on our experiences growing a code base to support the backend for RumbleTV Baseball and RumbleTV Football. I've posted the slides with notes. Happy to answer any questions.

Tags: javascript nodejs programming

April 24, 2012

JSCoverage Report for Jasmine

Wanted to announce the first release of a Jasmine reporter that we've been using in combination with JSCoverage and jasmine-node to capture code coverage metrics and produce an Emma style coverage report. The output of this get consumed by our Jenkins build and gives us nice coverage trends and detailed information for each build. As this is the first public release it is a little rough around the edges but is getting the job done. If anyone wants to check it out you can find it at:

npm install jscoverage-reporter

https://github.com/NeoPhi/jscoverage-reporter

Tags: jasmine jscoverage nodejs

April 24, 2012

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

February 26, 2012

An object unlike others: process.env

Yesterday I found myself playing with a configuration hierarchy. Anything set in the environment would override anything defined by a defaults.json file which would override anything hardcoded into the application. My initial attempt led me to discover some interesting things about node's process.env object. Without further ado:

console.log(process.env.hasOwnProperty('PROPERTY_NAME'));

Any guesses what the output will be?

With node 0.6.10 I get:

TypeError: Property 'hasOwnProperty' of object #<error> is not a function

Not what I was expecting. What about a different test:

console.log('hasOwnProperty' in process.env);
// output -> true
console.log(process.env.hasOwnProperty);
// output -> undefined

Fun. I've not look at the node source but given that the environment could define a property called hasOwnProperty it makes sense that process.env masks the standard prototype model even if the in operator exposes it.

Besides being a fun exercise playing with node, why does this matter you might ask? What started this all was detecting if an environment variable existed but was set to the empty string. The standard if check fails:

// This simulates launching node like: EMPTY= node env.js
process.env.EMPTY = '';
if (process.env['EMPTY']) {
    console.log('EXISTS');
} else {
    console.log('DOES NOT EXIST');
}
// output -> DOES NOT EXIST

Since the empty string is falsy in JavaScript this doesn't work. As we saw above doing a hasOwnProperty check won't work and the in operator could give false positives.

Thinking outside the box, given that the source of the values in process.env is the environment node was launched from, we know that the environment can't set a property value to be undefined. The simple existence check then is to see if the value is undefined:

console.log(typeof process.env['EMPTY'] !== 'undefined');

Or just use underscore's isUndefined method since you should be using that library anyway.

UPADTE
Just because we can't call hasOwnProperty() directly on process.env doesn't mean we can't still use it. Instead we just need to call it indirectly:

console.log(Object.prototype.hasOwnProperty.call(process.env, 'EMPTY'));
// output -> false
process.env.EMPTY = undefined;
console.log(Object.prototype.hasOwnProperty.call(process.env, 'EMPTY'));
// output -> true
process.env.EMPTY = '';
console.log(Object.prototype.hasOwnProperty.call(process.env, 'EMPTY'));
// output -> true


Tags: javascript nodejs