Incorrect handling of SIGHUP
See original GitHub issueI think the implementation of handling of SIGHUP is not 100% correct.
The proper handling of SIGHUP is to terminate the application and its children, but nodemon restarts the child instead.
The changes in SIGHUP handling were introduced with PR #1167 (commit 30f999a0). This commit introduced the feature to allow restarting child by sending SIGHUP to nodemon process. While the feature itself if fine, the choice of the signal, in my opinion, is not 100% correct. It think it would be better to always use SIGUSR2 for triggering restart. The details are below.
Expected behaviour
nodemon should terminate its child and itself upon receiving SIGHUP signal.
Actual behaviour
nodemon restarts the child.
Steps to reproduce
Use the following application:
const fs = require('fs')
fs.writeFileSync('signals.log', 'Log start\n')
function log (msg) {
fs.writeFileSync('signals.log', msg + '\n', { flag: 'a' })
}
var counter = 1
setInterval(() => log(counter++), 1000)
With Visual Studio Code
- Launch VS Code, open folder with the nodemon repository
- Save the sample code as
signals-test.js - Open integrated terminal (<kbd>Ctrl</kbd> + <kbd>`</kbd>)
- Run the following command:
node bin/nodemon.js signals-handler.js
- For convenience, open
signals.login VS Code editor (it automatically reloads log file after changes). Alternatively, run the following command in another terminal:
tail -f signals.log
- Close the integrated VS Code terminal by clicking the trashcan icon
Notice the updates to signals.log file are restarted and continue from the background instance of the signals-test.js.
With ssh
- Install and configure ssh server
- Connect to the machine via ssh. It is ok to connect to localhost for this test.
- Change dir to the nodemon repository
- Run the following command in ssh session:
node bin/nodemon.js signals-handler.js
- In another terminal also change dir to nodemon repository and run the following command:
tail -f signals.log
- In yet another terminal kill the ssh client:
pkill -f ssh localhost
Notice the updates to signals.log file are restarted and continue from the background instance of the signals-test.js. Nodemon behaves like nohup utility for applications launched in ssh session.
Environment
nodemon: 2.0.2 (from sources in master) node -v: v12.14.0 Operating system/terminal environment: Ubuntu 18.04.3 LTS
Analysis
According to man 7 signal, SIGHUP is sent when “Hangup detected on controlling terminal or death of controlling process”. Similar description can be found in Node documentation.
Historically SIGHUP was useless for daemons because they have no controlling terminal. SIGHUP was then reused for triggering the reloading of daemon configs. However, the original handling is still valid and probably required for non-daemon apps, specifically, for applications started in the terminal.
How to test this behavior: run the sample code in the VS code terminal or via ssh directly, without nodemon. Then close the terminal or kill the client connection, just like described in the “Steps to reproduce section above”. Notice that the signals.log file is updated while terminal is open and updates stop when the terminal is closed. This is in the contrast to the launching the same code from under the nodemon.
Proposed fix
I’ve made a PR with one variant of the fix. It contains the following changes:
- Handle only SIGUSR2 to trigger reload
- On SIGHUP quit with corresponding error code
- Also added tests for SIGHUP in separate commit
Since this is a breaking change (though a minor one), I would like to propose alternative solutions:
- Specify signal for reload as a separate command line and config parameter, keep the current behavior as default if parameter is not specified. The disadvantage of this approach is that with VS Code and ssh the default behavior would be counterintuitive.
- Add a parameter to ignore reload signal and keep the current behavior as default. Same disadvantage as 1.
Alternatively, the parameter can be used to switch to old (current) behavior.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:3
- Comments:19 (12 by maintainers)

Top Related StackOverflow Question
Still not stale
I found this issue because it also gives me trouble. I use tmux when developing, and in some windows I run nodemon to run my web server in dev mode. When executing
:kill-sessionin tmux it sendsSIGHUPto all processes. What then happens is that nodemon restarts and the window that nodemon is in is destroyed. But my server is still running.So now I have an “invisible” process running and if I try to start up a new dev session it says that the port I use is already in use.
So what should happen in my specific case would be that 1 tmux sends SIGHUP to nodemon 2 nodemon sends SIGHUP to my application that can listen for this and stop itself 3 nodemon exists gracefully
PS stalebot is a bit aggressive IMHO.