Debugging Node.js Applications with Node Inspector
Debugging is an important part any sort of application development. If you have errors or unexpected results occurring in your code you need to be able to step through your code and find where things are going awry. Thus it is very important that you are able to see what is happening at specific times when your code is executing. There are some IDEs (integrated development environments like Visual Studio or Eclipse) where debugging for the native application language like C# or Java is all built right into the tools and you don’t have to do anything to set it up. At the time of this writing in the later part of the year 2015, there are a few IDEs such as WebStorm and Komodo IDE that natively support Node.js debugging but this is often the exception rather than the rule (at present). Node.js, being a younger and relatively more immature platform often does not have debugging for it natively implemented in most IDEs yet. Fortunately, there are often plugins available that will enable Node.js debugging within the IDE. Node.js tools for Visual Studio 2012 and 2013 is one example. Nodeclipse is a plugin that will enable Node.js debugging capabilities in Eclipse.
Because there are so many different development environments and workflows that different developers have different preferences for we won’t look at debugging Node.js applications in a specific IDE. But we will look at a specific debugger called Node Inspector. There are other Node.js debuggers out there and if you want to use another debugger that is fine. You would just have to look at the docs for that particular debugger. It should be noted that Node Inspector works in Chrome and Opera only. You have to re-open the inspector page in one of those browsers if another browser is your default web browser (e.g. Safari or Internet Explorer). This is another indicator that shows widespread support for many things in and within Node.js is not entirely quite there just yet. So much of the Node.js module ecosystem is community driven, which has very noticeable pros and cons. The upside to this it is that there are a lot of awesome components of functionality that you can leverage via installation with a simple $ npm install of a module. The downside of this environment is that support and/or consistency for bug fixes and releases can vary quite a bit depending on who’s module(s) you are using. Just as a personal opinion, I find that on the whole the positives outweigh the negatives when it comes to open source software. I would much rather take this scenario over, say, a behemoth corporation owning and managing all of the releases that might seem more “professional” in its support and maintenance (as opposed to hobby/side-project code). But developing in and for open source applications is definitely far from perfect.
But all that aside, let’s get back to fun with Node.js debugging. Node Inspector works almost exactly as the Google Chrome Developer Tools. If you are not entirely familiar with Google Chrome’s developer tools read the DevTools overview to get started. Dev Tools can be used to set breakpoints in your application that halt the execution of the code when a certain statement (or statements) are reached. From there you can examine the state of particular objects to see what values they contain at that point in time. You can then step through your code moving from one statement to the next to see how the values change. If this all seems a little bit confusing at this point, not to worry. We will revisit this a bit later when we actually take on the task of debugging our application. But first we need to install the stuff we need to get debugging up and going.
Installing Node Inspector
To install Node inspector we will use the npm utility to install Node Inspector from npm.
$ sudo npm install -g node-inspector
Note: Windows 8.1 Users: At the time of this writing in the later part of 2015 for Windows 8.1 I had to omit installing an optional dependency which apparently breaks the install using npm. The way that you do this is by setting the –no-optional flag…
$ npm install -g node-inspector --no-optional
That should get it working for you. To check that it installed correctly you can always run
$ node-debug --version
which should output the version number for you without any error messages.
Sample Application
For our application we will use a sample API that I often utilize for demonstrating Node.js applications that uses Express.js as an application framework. If you are not familiar with Express there is an introduction to Express here. If you need a quick refresher on Node.js by any chance you can read A Node.js Primer. For a more in-depth look at Express.js, there is also an ongoing series entitled Creating an MVC Express.js Application.
We will start out by creating a package.json file and placing the following code within it…
{ "name": "Node.js-API", "description": "An API in Node.js...", "version": "0.0.1", "repository": { "type": "", "url": "" }, "dependencies": { "express": "4.4.4", "express-session": "1.5.1", "basic-auth": "1.0.3", "cookie-parser": "1.3.1", "body-parser": "1.4.3", "hbs": "3.1.0", "morgan": "1.1.1", "method-override": "2.0.2", "errorhandler": "1.1.1" } }
We then run
$ npm install
to install all the dependencies.
Next, create a file called server.js with the following code…
var express = require('express'); var bodyParser = require('body-parser'); var cookieParser = require('cookie-parser'); var session = require('express-session'); var logger = require('morgan'); var methodOverride = require('method-override'); var errorHandler = require('errorhandler'); var http = require('http'); var path = require('path'); var app = express(); app.set('port', 1337); app.set('view engine', 'html'); app.engine('html', require('hbs').__express); /* Morgan - https://github.com/expressjs/morgan HTTP request logger middleware for node.js */ app.use(logger({ format: 'dev', immediate: true })); /* cookie-parser - https://github.com/expressjs/cookie-parser Parse Cookie header and populate req.cookies with an object keyed by the cookie names. */ app.use(cookieParser('SECRETCOOKIEKEY123')); /* body-parser - https://github.com/expressjs/body-parser Node.js body parsing middleware. */ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); /* method-override - https://github.com/expressjs/method-override Lets you use HTTP verbs such as PUT or DELETE in places where the client doesn't support it. */ app.use(methodOverride()); app.use(express.static(path.join(__dirname, ''))); /* errorhandler - https://github.com/expressjs/errorhandler Show errors in development. */ app.use(errorHandler({ dumpExceptions: true, showStack: true })); // send app to router require('./router')(app); http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); });
Next create a file called router.js with the following code…
// Routes module.exports = function(app){ // index.html app.get('/', function(request, response){ response.render('index', {}); }); // API var artists = [ { id: 1, name: 'Notorious BIG', birthday: 'May 21, 1972', hometown: 'Brooklyn, NY', favoriteColor: 'green' }, { id: 2, name: 'Mike Jones', birthday: 'January 6, 1981', hometown: 'Houston, TX', favoriteColor: 'blue' }, { id: 3, name: 'Taylor Swift', birthday: 'December 13, 1989', hometown: 'Reading, PA', favoriteColor: 'red' } ]; // GET /api/artists app.get('/api/artists', function(request, response){ response.json(artists); }); // GET /api/artist/:id app.get('/api/artist/:id', function(request, response){ var id = request.params.id; var obj = artists[id - 1]; response.json(obj); }); };
And lastly we will create an index.html file as a homepage…
<!DOCTYPE html> <html> <head> <title>App</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <h1>Node.js Example</h1> <p>A basic example showing an API in Node.js</p> <p>Go to <a href="/api/artists">/api/artists</a> to view a JSON response of all artists</p> <p>Go to <a href="/api/artist/1">/api/artist/1</a> or <a href="/api/artist/2">/api/artist/2</a> to view a JSON response of an individual artist</p> </body> </html>
Now to run the application you simply have to open a terminal /command window and type the following…
$ node server
You should see a message logged to the screen that the Express server is running on port 1337. Press Ctrl+C or Cmd+C to quit.
Debugging With Node Inspector
To debug our application with Node Inspector, instead of running our application with the “node” command as we did above we can run it with node-debug instead…
$ node-debug server
This will open up a tab in your browser. As mentioned previously it will look a lot like Google Chrome’s dev tools because it uses a lot of the same structure from dev tools. By default the tools should stop the execution of the code at the first statement of the application as is shown.
You can see all of the files that are present in our application (as well as the modules we have installed on the left).
To set some breakpoints you can click on the line numbers in the code like as is shown in the following screenshot.Try placing a breakpoint inside one of the routes (the “/api/artists” route) on the response statement. Next in your browser navigate to the “/api/artists” route. If all goes well script execution should stop on that statement. From here you can hover over different objects such as the request and the response object and and examine the different properties on them.
Obviously this is a simple example. But as your application gets more complex debugging can be a powerful tool to track down errors that occur in Node.js applications. You could even use the “step into” button to step through individual modules as they are used. Hopefully this simple guide has helped you get on your way.
Until next time, happy debugging!

0 Responses to Debugging Node.js Applications with Node Inspector