I've come across a problem on one of my Nodejs apps running with npm start
(which just does node app.js
).
My app contains a sigint handler as follows:
process.on('SIGINT', () => {
db.disconnect().then({
process.exit(0);
}).catch(e => process.exit(1));
});
With corresponding logs. After some testing on other files, I've noticed that Ctrl-C when on an npm
process triggers SIGINT twice if the first one takes too long to exit. (try adding a timeout on a sample app).
For now I've added a counter to check if the call is performed more than once, but I'm not sure that's "the way to go" concerning this issue. I'm guessing that a SIGINT on an npm process is expected to quit in a certain timeframe, which is why npm passes it on one more time (always only twice).
Has anyone come across this problem and found a viable solution?
Thanks!
I know this post has been around for a while but unfortunately I'm getting the same issue. When running just node <app.js>
it fires just one signal. That signal comes twice if running npm start
.
Instead a counter, I suggest check if the server is still listening, if yes, proceed with your logic and internal termination (like db connections etc):
process.on('SIGINT', function(){
if (server.listening) {
server.close(function (err) {
if (err) {
console.error(err);
process.exit(1)
}
process.exit(0);
})
}
})
You might want to run your command's directly via node, rather than via npm start
. NPM can be a cause for wierd trapping of signals, see https://lisk.io/blog/tutorial/why-we-stopped-using-npm-start-child-processes.
Your SIGINT handler can get called multiple times, you should write your code to protect against that.
Also if you are running parent/child processes, see https://github.com/jtlapp/node-cleanup
When you hit Ctrl-C, you send a SIGINT signal to each process in the current process group. A process group is set of processes that are all supposed to end together as a group instead of persisting independently. However, some programs, such as Emacs, intercept and repurpose SIGINT so that it does not end the process. In such cases, SIGINT should not end any processes of the group.
Additionally, calling process.exit is not necessary most of the time, see https://nodejs.org/api/process.html#process_process_exit_code
Instead set process.exitCode
, remove your signal handlers and then re-raise the signal via process.kill(process.pid, signal)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With