You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Microsoft Windows NT 10.0.19045.0 x64 (Windows 10 Pro 22H2)
Subsystem
No response
What steps will reproduce the bug?
The example code is heavily inspired by Prompts library as I've struggled the issue while using this lib. I've also created an issue there, but it seems that the problem is likely in Node.
The example code is roughly re-written Prompts library code that is only responsible for receiving text input, with all irrelevant details omitted. There, the input function waits you to enter some text, records and echoes pressed keys, and when Enter key is pressed, the function finishes its execution and returns what user entered.
Please notice that we pass asyncAction to the first input invocation and only to it — this is the reason of all troubles (though it is expected to work perfectly).
To reproduce the issue:
Make sure you're doing this on Windows :)
Run this code
Enter some text for the first input, make sure that key presses are echoed back, and press Enter
Do the same for the second input
Start entering text for the third input. Here is where problems begin, key presses are not echoed back as keypress events are not triggered
const{ stdin, stdout }=require('process');constreadline=require('readline');// makes input stream emit 'keypress' eventsfunctioncreateReadline(is,keypress){constrl=readline.createInterface({input: is,escapeCodeTimeout: 50});readline.emitKeypressEvents(is,rl);if(is.isTTY){is.setRawMode(true);}is.on('keypress',keypress);// return a callback that stops emitting 'keypress' events and frees resourcesreturn()=>{is.removeListener('keypress',keypress);if(is.isTTY){is.setRawMode(false);}rl.close();};}// determine what is needed to do for a key object sent by 'keypress' eventfunctiongetActionName(key){functionneedFinish(key){return(key.ctrl&&['c','d'].includes(key.name))||key.name=='escape'||['enter','return'].includes(key.name);}functiondoNothing(key){return['backspace','delete','abort','escape','tab','pagedown','pageup','home','end','up','down','right','left'].includes(key.name)||key.ctrl;}if(doNothing(key)){return'noop';}if(needFinish(key)){return'finish';}return'add-letter';}// listen to keypresses until user presses Enter, and then return concatenated lettersfunctioninput(is,os,onEndInput=()=>undefined){returnnewPromise((resolve)=>{os.write('Enter string letter by letter, then press Enter\n');letresult='';constcloseReadline=createReadline(is,keypress);functionkeypress(_,key){os.write(`Encountered ${key.name}\n`)constactionName=getActionName(key);if(actionName=='finish'){endInput();}elseif(actionName=='add-letter'){result+=key.name;}};asyncfunctionendInput(){awaitonEndInput();// <--- If onEndInput is an async function, then it causes the described problemcloseReadline();resolve(result);};});}asyncfunctionasyncAction(){awaitnewPromise((resolve)=>setTimeout(resolve,100));// Another example of async invocation that causes issues (node-fetch@2 is used): await fetch('https://jsonplaceholder.typicode.com/posts');// An example of code that does NOT cause issues: await Promise.resolve(0);}asyncfunctionmain(){awaitinput(stdin,stdout,asyncAction);awaitinput(stdin,stdout);awaitinput(stdin,stdout);}main();
How often does it reproduce? Is there a required condition?
Always reproduced, but only on Windows.
I tried running the example on WSL, no issue there.
What is the expected behavior? Why is that the expected behavior?
All key presses for all user prompts should be triggered correctly and echoed back by the example code
What do you see instead?
When the program awaits user to enter text for the third prompt, no keypress events are triggered, until user presses Enter. And only then, instead of finishing execution, input function starts recording user input.
Additional information
No response
The text was updated successfully, but these errors were encountered:
I'm not able to reproduce and it doesn't look like we've received similar reports so I'm inclined to write this off as something local to your setup. (Terminal software maybe?)
If you can track down the root cause, we can decide if it's something node could reasonably handle. Otherwise please go ahead and close this.
I can reproduce the issue by running the provided code.
Windows, Node v16.14.0, Git Bash/PowerShell/cmd
Wrapping closeReadline(); resolve(result); into setTimeout resolves the issue (actually making all subsequent inputs closing async resolves it):
async function endInput() {
await onEndInput(); // <--- If onEndInput is an async function, then it causes the described problem
setTimeout(() => {
closeReadline();
resolve(result);
}, 0);
}
Wrapping the same into process.nextTick does not resolve it.
Additionally, it's only reproducible for readStream.setRawMode(true).
The other observation is that the issue is actually reproducible for two input requests:
Here the terminal is waiting for Enter after the second interface is closed
The issue looks related to #38663, where commenting out readStream.setRawMode(false) resolves the issue, but I guess may have some negative impact for the program.
Version
20.6.1
Platform
Microsoft Windows NT 10.0.19045.0 x64 (Windows 10 Pro 22H2)
Subsystem
No response
What steps will reproduce the bug?
The example code is heavily inspired by Prompts library as I've struggled the issue while using this lib. I've also created an issue there, but it seems that the problem is likely in Node.
The example code is roughly re-written Prompts library code that is only responsible for receiving text input, with all irrelevant details omitted. There, the
input
function waits you to enter some text, records and echoes pressed keys, and when Enter key is pressed, the function finishes its execution and returns what user entered.Please notice that we pass
asyncAction
to the firstinput
invocation and only to it — this is the reason of all troubles (though it is expected to work perfectly).To reproduce the issue:
keypress
events are not triggeredHow often does it reproduce? Is there a required condition?
Always reproduced, but only on Windows.
I tried running the example on WSL, no issue there.
What is the expected behavior? Why is that the expected behavior?
All key presses for all user prompts should be triggered correctly and echoed back by the example code
What do you see instead?
When the program awaits user to enter text for the third prompt, no keypress events are triggered, until user presses Enter. And only then, instead of finishing execution,
input
function starts recording user input.Additional information
No response
The text was updated successfully, but these errors were encountered: