Restart NodeJs Server on error, handle exceptions

NodeJs Essentials: How to restart your nodeJs server programmatically in the event of a failure

You are excited about your new found love for NodeJs and you start creating an application. You have some REST apis wired up and you are all set to change the world! But for some reason, you have some unhandled error in your code and your nodeJs server crashes! Now you got to restart it to make sure it stays up. Ever crossed this scenario? If so, this is for you.

To demonstrate this, let’s look at the below scenario


http.createServer(function (request, response) {
console.log('Ready to accept request');
response.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin' : '*'
});
response.end('Hello World\n');
}).listen(1337);

This is a very simple http server that sends ‘Hello World’ as a response to the requester. To run this program,

  • Save the code above to a file (e.g. hello-world.js)
  • Go to terminal and locate the file. Run node hello-world.js
  • Access ‘http://localhost:1337’ to see the response on your browser/REST client like below
    NodeJs hello world http server

What a happy world!

Your nodeJs program worked!

Now all is fine, until there is an error in your code and your app crashes! Lets simulate this by the below code. Notice, how I am trying to access a property of variable ‘i’ which is not defined.

var http = require('http');
http.createServer(function (request, response) {
console.log('Ready to accept request');
// This line below is going to break your server!
var j = i.someProperty;
response.writeHead(200, {
'Content-Type': 'text/plain',
'Access-Control-Allow-Origin' : '*'
});
response.end('Hello World\n');
}).listen(1337);

Run this code, and hit the http://localhost:1337 url and you will see that the server fails with the below message.

ReferenceError: n is not defined
at Server. (/Users/srijithradhakrishnan/Desktop/httpServer.js:5:17)
at emitTwo (events.js:106:13)
at Server.emit (events.js:191:7)
at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:543:12)
at HTTPParser.parserOnHeadersComplete (_http_common.js:105:23)

So, how do we recover from a failure like this and keep the server running? For this, we could use the cluster module from nodeJs. Here is how it could be used.


var http = require('http');
var cluster = require('cluster');
// The master's job to spawn workers initially and when they die
if (cluster.isMaster) {
// Get the number of processor cores
var cpuCount = require('os').cpus().length;

// Create a worker for each CPU
for (var i = 0; i < cpuCount; i += 1) { cluster.fork(); } // When a worker exits, fork a new one cluster.on('exit', function(worker) { console.log('Worker %d died', worker.id); cluster.fork(); }); } else if (cluster.isWorker) { // The real work here for the worker http.createServer(function (request, response) { console.log('Ready to accept request'); // This will cause the server to crash var i = n.start; response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin' : '*' }); response.end('Hello World\n'); }).listen(1337); // Exit the process when there is an uncaught exception console.log('Worker %d running!', cluster.worker.id); process.on('uncaughtException', function() { console.log('Handled the exception here'); process.exit(1); }); }

  • Now, run the code.
  • See that the master has spawned as many workers are there are cores in your cpu. So if you have a four code CPU, you should see 4 workers spawned!
  • hit the 'hello world' api, you would see that one of the workers died but was respawned again by the master.

Thus your nodeJs server can live on for eternity!

(ok that was too much, but you get the point!)

2 thoughts on “NodeJs Essentials: How to restart your nodeJs server programmatically in the event of a failure”

  1. Good to see additional pages showing up in quick time! Congrats to both bloggers who made a good start. Way to go! Nice post btw. Would recommend sharing option in the posts.

Leave a Reply

Your email address will not be published. Required fields are marked *