How to properly handle SIGINT with Express.js?

Jacob Marble picture Jacob Marble · Jan 17, 2013 · Viewed 20.1k times · Source

I need to do some useful things when my Express.js service is stopped by SIGINT. Using Express.js version 3.0.6, I understand that this should work:

var express = require('express');

var app = express();
var server = app.listen(3000);

process.on('SIGINT', function() {
  console.log('Do something useful here.');
  server.close();
});

But the process doesn't give me back the Bash prompt unless I issue SIGINT (Control-C) twice:

$ node problem.js 
^CDo something useful here.
^CDo something useful here.

net.js:1046
    throw new Error('Not running');
          ^
Error: Not running
    at Server.close (net.js:1046:11)
    at process.<anonymous> (/path/to/problem.js:8:10)
    at process.EventEmitter.emit (events.js:93:17)
    at SignalWatcher.startup.processSignalHandlers.process.on.process.addListener.w.callback (node.js:486:45)
$

One more caveat. If I start this Express.js service and don't send any requests then SIGINT terminates properly.

Clearly there is something fundamental that I'm missing here?

Answer

nneonneo picture nneonneo · Jan 17, 2013

By catching the SIGINT handler, you are preventing the default behaviour, which is to quit the process. When you use Ctrl+C the second time, the process dies because server.close throws an uncaught exception.

Just add a process.exit() to the end of your SIGINT handler to quit the process gracefully.