Giter Site home page Giter Site logo

Comments (12)

xxn520 avatar xxn520 commented on July 22, 2024 1

Thanks! I'll get back to this when I have some spare time. Appreciate the time you took to debug this

hi, whether there is progress. I have the same problem on windows.

from prompts.

fabsenet avatar fabsenet commented on July 22, 2024

If I change my script to contain more than one prompt, I can successfully cancle the second prompt, but not the first one:

var prompts = require("prompts");

async function main() {
  var prefix1 = await prompts({
    type: "text",
    name: "prefix1",
    message: "Prefix1!"
    //    initial: "muh"
  });
  console.log(prefix1);

  var prefix2 = await prompts({
    type: "text",
    name: "prefix2",
    message: "Prefix2!"
    //    initial: "muh"
  });
  console.log(prefix2);
}

main();

grafik

from prompts.

fabsenet avatar fabsenet commented on July 22, 2024

If I press Escape really fast at least 3 times on the first prompt, it will not hang. 💣

from prompts.

terkelg avatar terkelg commented on July 22, 2024

Hi @fabsenet, thanks for reporting the issue. Can you help with this one? I can't reproduce it on my Mac. It could be super helpful.

from prompts.

fabsenet avatar fabsenet commented on July 22, 2024

I digged a lot and seems strange!

this diff solves hides the error:

diff --git a/lib/elements/text.js b/lib/elements/text.js
index 665c5bd..364a1c5 100644
--- a/lib/elements/text.js
+++ b/lib/elements/text.js
@@ -51,7 +51,8 @@ class TextPrompt extends Prompt {
     this.render();
   }

-  abort() {
+  async abort() {
+    await (async () => true)();
     this.value = this.value || this.initial;
     this.done = this.aborted = true;
     this.error = false;

If I make the abort function async and I need to await something before the close() call, it works (and it mirors what submit does!)

what I learned while debugging is await prompt(questions); return with an empty object but the next console.log hangs. I think something with handling of keypress, stdin, stdout, setraw ... is not properly cleaned up? console stuff is most probably system-dependent and therfor not broken on mac?

from prompts.

fabsenet avatar fabsenet commented on July 22, 2024

I found another way to solve hide the error:

diff --git a/lib/elements/prompt.js b/lib/elements/prompt.js
index 57e228b..dc0037e 100644
--- a/lib/elements/prompt.js
+++ b/lib/elements/prompt.js
@@ -36,7 +36,7 @@ class Prompt extends EventEmitter {
     const close = () => {
       this.out.write(cursor.show);
       this.in.removeListener('keypress', keypress);
-      if (this.in.isTTY) this.in.setRawMode(false);
+ //     if (this.in.isTTY) this.in.setRawMode(false);
       rl.close();
       this.emit(this.aborted ? 'abort' : 'submit', this.value);
     };

the problem here is, the stdin stays in raw mode after the prompt call but I can do this without blocking in example:js:

    const answers = await prompt(questions);
    const q = process.stdin;
    q.setRawMode(false);
    console.log("If you can read this, it does not block! israw = ", q.isRaw);
    console.log(answers);

I find this all so strange and pointing to a platform error but on the other side select aint broken ... I do not know how to further pinpoint this :-(

from prompts.

fabsenet avatar fabsenet commented on July 22, 2024

my window server 2016 was using node 10.3, i upgraded to 10.9 without any changes.

my notebook is running windows 10 with node 10.9 already and cancelling just works as expected in cmd, powershell and the vs code integrated shell.

I learned a lot about debugging node but as for the actual issue: I am not going to invest any more time on this but maybe someone else will find this issue and will enlighten us, as i am very interested in the root cause!

from prompts.

terkelg avatar terkelg commented on July 22, 2024

Thanks! I'll get back to this when I have some spare time. Appreciate the time you took to debug this

from prompts.

stsourlidakis avatar stsourlidakis commented on July 22, 2024

This is still an issue, I tried the following autocomplete example from the docs on Windows 10 (build 19041).

  • PowerShell or cmd: after pressing the escape key the prompt hangs until you press ctrl+c.
  • Ubuntu shell(WSL2 with Ubuntu 18.04 or 20.04): after pressing the escape key the highlighted option gets selected (same behavior with enter).
const prompts = require('prompts');

(async () => {
	const response = await prompts({
		type: 'autocomplete',
		name: 'value',
		message: 'Pick your favorite actor',
		choices: [
			{ title: 'Cage' },
			{ title: 'Clooney', value: 'silver-fox' },
			{ title: 'Gyllenhaal' },
			{ title: 'Gibson' },
			{ title: 'Grant' },
		],
	});

	console.log(response);
})();

from prompts.

AsceticBoy avatar AsceticBoy commented on July 22, 2024

Thanks! I'll get back to this when I have some spare time. Appreciate the time you took to debug this

same problem with me in windows, whether there is in progress?

from prompts.

daydayhappychao avatar daydayhappychao commented on July 22, 2024

人呢老哥,看下问题呗 @terkelg

from prompts.

raulfdm avatar raulfdm commented on July 22, 2024

I've made some experiments on that and it seems there's ways to prevent such behaviour.

First I have to say that, indeed, the library has a problem to abort the pending promises til in the latest version (2.4.2). It's easy to prove that by running the following code:

import prompts from 'prompts'
;(async () => {
  const { actor } = await prompts({
    type: 'autocomplete',
    name: 'actor',
    message: 'Pick your favorite actor',
    choices: [
      { title: 'Cage' },
      { title: 'Clooney', value: 'silver-fox' },
      { title: 'Gyllenhaal' },
      { title: 'Gibson' },
      { title: 'Grant' },
    ],
  })

  const { prefix } = await prompts({
    type: 'text',
    name: 'prefix',
    message: 'Prefix!',
  })

  console.log('Hey')
  await sleep(2000)
  console.log('You', { prefix, actor })
})()

function sleep(ms = 0): Promise<void> {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`AWAKE AFTER ${ms}ms`)
      resolve()
    }, ms)
  })
}

Once you run this program, the stdin will be blocked (so we can interact it with). However, by pressing CMD + C (or CTRL + C I assume for Linux/Windows Users), instead the prompt aborts and terminates with process.exit(1), it somehow continues.

Terminal output:

> tsx src/index.ts

✖ Pick your favorite actor › Cage
✖ Prefix! … 
Hey
AWAKE AFTER 2000ms
You { prefix: undefined, actor: undefined }

Workaround

I notice that when we create a prompt we can pass an option called onCancel. As the docs said:

Callback that's invoked when the user cancels/exits the prompt. Its signature is (prompt, answers) where prompt is the current prompt object and answers the user answers so far. Async functions are supported.

Return true to continue and prevent the prompt loop from aborting. On cancel responses collected so far are returned.

So, if you're running into such problem, maybe a solution would be passing a callback that forces the program to exit:

import prompts from 'prompts'

// Here our callback to terminate
function exitError() {
  process.exit(1)
}

;(async () => {
  const { actor } = await prompts(
    {
      type: 'autocomplete',
      name: 'actor',
      message: 'Pick your favorite actor',
      choices: [
        { title: 'Cage' },
        { title: 'Clooney', value: 'silver-fox' },
        { title: 'Gyllenhaal' },
        { title: 'Gibson' },
        { title: 'Grant' },
      ],
    },
    {
      onCancel: exitError, // <- declare it here
    }
  )

  const { prefix } = await prompts(
    {
      type: 'text',
      name: 'prefix',
      message: 'Prefix!',
    },
    {
      onCancel: exitError, // <- declare it here
    }
  )

  console.log('Hey')
  await sleep(2000)
  console.log('You', { prefix, actor })
})()

function sleep(ms = 0): Promise<void> {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log(`AWAKE AFTER ${ms}ms`)
      resolve()
    }, ms)
  })
}

Now, by running this program and forcing exit, it'll do it immediately:

Terminal output:

> tsx src/index.ts

✖ Pick your favorite actor › Cage
 ELIFECYCLE  Command failed with exit code 1.

Try it yourself

from prompts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.