naopoyo.com
  • Docs
  • Tags
  • Bookmarks
  • Tools
  • About
  • Docs
  • Tags
  • Bookmarks
  • Tools
  • About

目次

© naopoyo

目次

最近更新された記事

📦

Changesets でモノレポのリリースを自動化する(個人開発向け設定)

約1時間前·2026年01月31日
  • Changesets
  • npm
  • GitHub
🎤

GitHub Actions で npm パッケージを公開する(アルファ版向け簡易フロー)

約4時間前·2026年01月31日
  • GitHub
  • npm
✒️

エンジニア個人ブログまとめ

1日前·2026年01月30日
  • デザイン
  • Next.js
  • Markdown
⌨️

@inquirer/prompts で Ctrl+C をユーザーフレンドリーに処理する

公開日約5時間前2026-01-31
履歴GitHubで見る
MarkdownRaw Content
  • Node.js
  • TypeScript

問題

@inquirer/prompts を使った CLI ツールで、ユーザーが Ctrl+C でプロンプトを中断すると、以下のような例外のスタックトレースが表示されてしまう。これはユーザー体験として良くない。

Terminal
ExitPromptError: User force closed the prompt with 0 null
    at /path/to/node_modules/@inquirer/core/dist/esm/index.js:123:45
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    ...

原因

@inquirer/prompts では、ユーザーが Ctrl+C を押すとプロンプトの Promise が reject される。この際に ExitPromptError という名前のエラーがスローされる。

これは意図的な設計で、アプリケーションがクリーンアップ処理を行えるようにするためのもの。しかし、適切にハンドリングしないとスタックトレースがそのまま表示されてしまう。

解決策

グローバルな uncaughtException ハンドラを設定して、ExitPromptError の場合はユーザーフレンドリーなメッセージを表示する。

ポイント: instanceof は使わない

ExitPromptError クラスを直接インポートして instanceof でチェックする方法は、パッケージの構造上うまく動作しないケースがある。

代わりに error.name === 'ExitPromptError' でチェックするのが推奨されている。

実装例

/**
 * プロンプトがキャンセルされたエラーかどうかを判定する
 */
function isPromptCancelled(error: unknown): boolean {
  return error instanceof Error && error.name === 'ExitPromptError';
}

// グローバルエラーハンドラ
process.on('uncaughtException', (error) => {
  if (isPromptCancelled(error)) {
    console.log('\nCancelled.');
    process.exit(0);
  }
  throw error;
});

これだけで、CLI のどこで Ctrl+C が押されても適切に処理される。

結果

修正前:

Terminal
? Enter title › ^C
ExitPromptError: User force closed the prompt with 0 null
    at /path/to/node_modules/@inquirer/core/dist/esm/index.js:123:45
    ...

修正後:

Terminal
? Enter title › ^C
Cancelled.

参考リンク

  • Handle ctrl+c gracefully · Issue #1502 · SBoudrias/Inquirer.js
  • instanceof always returning false when checking for ExitPrompError errors · Issue #1475
  • @inquirer/prompts - npm