-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Have to send two SIGINT to kill when prompt is open #293
Comments
Inquirer shouldn't trap SIGINT. What's your OS/terminal/node version? |
Interesting...I tried to create a minimal repro but couldn't reproduce the behavior. I thought I had seen the behavior in |
I ran into this issue recently. Because of Inquirer.js's usage of For me, the problem came up when I had a child process running. Since Inquirer does not propagate the signal, it is never exposed to the main process. This essentially removes any ability to listen for any signals with The real question is, should SIGINT only go to Inquirer, and be required a second time for the process, or should Inquirer be responsible and ensure that SIGINT is sent properly? |
@ChristianAlexander can you link to the Node documentation stating that readlines won't propagate signals to the process? |
After looking into this further, there is no documentation explicitly stating that signals do not propagate. In fact, manually sending a SIGINT (ex: The problem is that readline itself listens to the TTY directly, so a 'real' SIGINT isn't produced. |
@ChristianAlexander mind opening an issue on Node and linking this issue? |
I'm unsure if this should be considered an issue at the Node level. Perhaps there could be a case where it wouldn't be desirable to send a SIGINT on However, I can not come up with a scenario where any Inquirer-based projects would use If Inquirer doesn't end up sending SIGINTs to the process itself, would it be possible to have Inquirer pass the event along after it is done closing up? If not, could Inquirer send an error object in its callback where results are sent? |
I don't know, but that seems like a conversation worth having with the Node community.
Feel free to send a PR. |
So... |
@felipenmoura these events are global, you don't need to listen to it on inquirer. |
Well, they are not being triggered! |
@felipenmoura that's what this thread is saying. That's due to the Node.js readline. You guys should open an issue on the Node project. |
What about some kind of solution like exposing the readline instance as a workaround? See this comment from a Node.js Foundation Member: nodejs/node#4758 (comment) |
Does anyone have any new insights or workarounds for this issue? It's still present one year on and quite annoying that one has to CTRL-C twice to exit a process where inquirer prompt is active. Looks like the suggestion as above by @dcrockwell is already present in the code but to no avail: https://github.com/SBoudrias/Inquirer.js/blob/master/lib/ui/baseUI.js#L21 Further investigation shows that the called
I'll create a PR to fix this. |
I disagree with the recently merged The application making use of inquirer may wish to do unrelated cleanup via The correct way to handle this is |
@welwood08 I can confirm that using |
As per #293 (comment), this change still keeps the desired behaviour of killing the process on CTRL-C, but it gives parent processes a chance to clean up.
I just tried with the version 6.x and my SIGINT handler never gets called unless I remove this line: |
I also have the same problem in the 6.x version.I found the problem is in this.close() method in ui/baseUI.js.More specific is the combination of this.rl.pause()
this.rl.close(). I also look the pause and close method in node readline.js.But I can not find the reason. |
EDIT: I guess this is more a comment on the issue that b4dnewz & junfeisu had, rather than the OP, in that I couldn't catch my SIGINT at all (I did not have to send it to my process twice). Still, I hope this is helpful for others that land here looking for signal handling issues I thought I was hitting this issue with version 6.2, but it turned out not to be an issue with inquirer, it was more with the way signal handlers work in node. Posting my solution here in case it's helpful for others: My issue was, in short You might think that your signal handler would be ref'ed by the event loop, as any socket listener or file read request is, but that is not the case. So even though you may have set a The solution was My implementation of this solution /**
* This class is required for proper signal handling of
* inquirer-based programs.
*
* USAGE:
*
* async function myTask() {
* // Create a signal ref for the signal you'd like to catch
* const signalRef = new SignalRef(
* 'SIGINT',
* () => { process.exit(1); }
* );
*
* try {
* await doYourInquirerStuff();
* } finally {
* // Release the ref to avoid keeping the loop alive forever.
* signalRef.unref();
* }
* }
*
* NOTE: If you're not going to exit in your signal handler,
* consider whether you want to catch the signal only once
* (in which case maybe have it unref itself) or many times.
*
* See: https://github.com/SBoudrias/Inquirer.js/issues/293
*/
module.exports = class SignalRef {
constructor(signal, handler) {
this.signal = signal;
this.handler = handler;
process.on(this.signal, this.handler);
// This will run a no-op function every 10 seconds.
// This is to keep the event loop alive, since a
// signal handler otherwise does _not_. This is the
// fundamental difference between using `process.on`
// directly and using a SignalRef instance.
this.interval = setInterval(() => {}, 10000);
}
unref() {
clearInterval(this.interval);
process.removeListener(this.signal, this.handler);
}
}; |
@jbreeden-splunk thanks! Is there a way to go back to the last prompt by inquirer after handling the signal? (ideally without bookkeeping from my end) |
Closing this ticket as stale. Open new issues if you encounter problem with the new Inquirer API. |
If you Ctrl-C out of a command while an inquirer prompt is open, it just adds a couple lines of space and then you have to Ctrl-C again to actually exit. I'd expect the calling program to be the one controlling what happens on SIGINT here.
Is this working as intended? If so, is there a way to be notified when Inquirer has trapped a SIGINT?
The text was updated successfully, but these errors were encountered: