You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用@inquirer/prompts连续调用两个Prompt时程序异常终止的问题

@inquirer/prompts连续调用两个Prompt时程序异常终止的问题

嘿,这个问题我之前用@inquirer的时候也踩过坑!你遇到的情况应该是第一个prompt处理Ctrl+C后,终端的交互状态没被正确重置,导致第二个prompt根本没法正常拉起交互环境,刚打印完消息就直接退出了。

咱们来拆解下原因:@inquirer底层依赖readline模块和终端交互,当你按下Ctrl+C触发SIGINT信号时,第一个prompt的try/catch虽然捕获了中断,但@inquirer内部可能已经关闭了readline实例、修改了终端的raw模式,甚至调整了默认的信号监听器。这时候第二个prompt启动时,发现终端环境不对,就直接默认退出了,所以你看到退出码是0(看似正常退出,但完全不是你想要的结果)。

给你几个实用的解决办法:

  • 手动恢复终端状态与信号监听
    在第一个prompt的catch块里,手动把终端恢复到原始模式,并且重置SIGINT的处理逻辑,这样第二个prompt就能正常初始化了。比如可以这么写:

    import { input, confirm } from '@inquirer/prompts';
    
    async function collectUserInputs() {
      try {
        while (true) {
          const inputValue = await input({ message: '输入内容(按Ctrl+C结束):' });
          // 这里处理你的输入逻辑
          console.log(`已接收输入: ${inputValue}`);
        }
      } catch (err) {
        console.log('\n输入收集完成');
        // 恢复终端的原始模式,不然后续prompt没法正常工作
        process.stdin.setRawMode(false);
        // 移除可能存在的自定义SIGINT监听器,交给第二个prompt自己处理
        process.removeAllListeners('SIGINT');
      }
    }
    
    async function main() {
      await collectUserInputs();
      // 现在第二个确认prompt就能正常工作了
      const confirmResult = await confirm({ message: '是否继续执行后续操作?' });
      console.log(`你的选择是: ${confirmResult}`);
    }
    
    main();
    
  • 别自己瞎绑定SIGINT监听器
    很多人会想着自己加process.on('SIGINT', ...)来处理中断,但其实@inquirer本身已经内置了SIGINT的处理逻辑,手动绑定反而会和它的内部逻辑冲突,导致终端状态混乱。就用try/catch捕获第一个prompt的中断就行,别画蛇添足。

  • 检查资源是否泄漏
    如果你的第一个循环里有其他和终端交互的资源(比如自己创建的readline实例),一定要在退出循环时关闭它们,不然这些资源会占用终端控制权,第二个prompt根本拿不到权限,自然就直接退出了。

备注:内容来源于stack exchange,提问作者Nipun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 16:19:35