44

In Express.js, is there someway of setting a callback function to be executed when the application shuts down?

William
  • 13,332
  • 13
  • 60
  • 73
  • 2
    The below answers are not useful in every day activity, you're looking for [this](https://stackoverflow.com/questions/14031763/doing-a-cleanup-action-just-before-node-js-exits) - process.on('SIGINT', () => { ...}) – mattyb Jun 23 '17 at 21:35

4 Answers4

45

You could use the node.js core process 'exit' event like so:

process.on('exit', function() {
  // Add shutdown logic here.
});

Of course, the main event loop will stop running after the exit function returns so you can't schedule any timers or callbacks from within that function (e.g. any I/O must be synchronous).

maerics
  • 151,642
  • 46
  • 269
  • 291
  • 1
    can I use `async function()` there ? – Hendy Irawan May 29 '19 at 21:45
  • 1
    @HendyIrawan yes you can use `async` – emc Mar 31 '20 at 18:25
  • 1
    @emc it's false! You can't use async code in 'exit' handler. See here: https://nodejs.org/api/process.html#process_event_exit "Listener functions must only perform synchronous operations". The best alternative I found so far to handle exit for any possible reason is handling each signal event, as described in this answer: https://stackoverflow.com/a/40574758/2879716 – Alexey Grinko Dec 09 '20 at 18:18
11

There is process.on('exit', callback):

process.on('exit', function () {
  console.log('About to exit.');
});
alessioalex
  • 62,577
  • 16
  • 155
  • 122
2

The express team recommends the terminus package:

https://expressjs.com/en/advanced/healthcheck-graceful-shutdown.html

Jonathan
  • 16,077
  • 12
  • 67
  • 106
1

If you need to access something in the current scope, you can bind() like in this answer: https://stackoverflow.com/a/14032965/1410035 but you might want to bind this.

function exitHandler(options, err) {
    if (options.cleanup) console.log('clean');
    if (err) console.log(err.stack);
    if (options.exit) process.exit();
}

process.on('exit', exitHandler.bind(null,{cleanup:true}));
Tom Saleeba
  • 4,031
  • 4
  • 41
  • 36
  • Or just use an arrow function. Its scope is wherever it's declared. `const exitHandler = (options, err) => {...}` – Eric Haynes Nov 20 '18 at 03:49