3

We're looking to use node.js for a highly dynamic project. Traditionally, we've used Java and, when faced with an unhandled exception, an error is thrown but the web application (usually) continues to serve other requests.

With node, however, the same scenario causes the process to terminate. I'd hate to think what would happen if we deployed this system to production and the whole server crashed because of an unhandled exception.

I was wondering if there are tutorials / tools / etc to help deal with the problem of dealing with exceptions. For example, is there a way to add a global last-resort-type exception that?

NRaf
  • 7,407
  • 13
  • 52
  • 91

3 Answers3

3
process.on('uncaughtException', function (err){
  console.error(err)
})
danmactough
  • 5,444
  • 2
  • 21
  • 22
3

As mentioned here you'll find error.stack provides a more complete error message such as the line number that caused the error:

process.on('uncaughtException', function (error) {
   console.log(error.stack);
});
Community
  • 1
  • 1
Sean Bannister
  • 3,105
  • 4
  • 31
  • 43
1

You should use Node.js domains:

The safest way to respond to a thrown error is to shut down the process. Of course, in a normal web server, you might have many connections open, and it is not reasonable to abruptly shut those down because an error was triggered by someone else.

The better approach is send an error response to the request that triggered the error, while letting the others finish in their normal time, and stop listening for new requests in that worker.

The linked pages has example code which I've simplified slightly below. It works as described above. You would either invoke your server in a way that it will automatically be relaunched when it exits, or use the worker pattern from the full example.

var server = require('http').createServer(function(req, res) {
  var d = domain.create();
  d.on('error', function(er) {
    console.error('error', er.stack);

    try {
      // make sure we close down within 30 seconds
      var killtimer = setTimeout(function() {
        process.exit(1);
      }, 30000);
      // But don't keep the process open just for that!
      killtimer.unref();

      // stop taking new requests.
      server.close();

      // try to send an error to the request that triggered the problem
      res.statusCode = 500;
      res.setHeader('content-type', 'text/plain');
      res.end('Oops, there was a problem!\n');
    } catch (er2) {
      // oh well, not much we can do at this point.
      console.error('Error sending 500!', er2.stack);
    }
  });

  // Because req and res were created before this domain existed,
  // we need to explicitly add them.
  d.add(req);
  d.add(res);

  // Now run the handler function in the domain.
  d.run(function() {
    // your application logic goes here
    handleRequest(req, res);
  });
});
Community
  • 1
  • 1
alltom
  • 3,162
  • 4
  • 31
  • 47