Node.js未処理Promise拒否の解析

Node.js UnhandledPromiseRejectionWarningスタックトレースを解析。Node.jsアプリケーションから非同期エラーコンテキスト、ファイルパス、拒否されたPromiseチェーンを抽出します。

JavaScript

詳細な説明

Node.js未処理Promise拒否の理解

UnhandledPromiseRejectionWarningはPromiseが拒否されたが、.catch()ハンドラーやasync関数内のtry/catchが存在しない場合に発生します。Node.js 15以降、未処理の拒否はデフォルトでプロセスを終了します。

スタックトレースフォーマット

UnhandledPromiseRejectionWarning: Error: Connection refused
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
    at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
    at Connection.query (/app/node_modules/mysql/lib/Connection.js:198:25)
    at DatabaseService.findUser (/app/src/services/database.ts:87:12)
    at UserController.getUser (/app/src/controllers/user.ts:34:20)

非同期スタックトレースの課題

Promiseベースのコードは非同期境界を作成し、スタックトレースチェーンを断絶させる可能性があります。Node.js 12で--async-stack-tracesが追加される前は、完全な非同期コールチェーンではなく拒否ポイントのみを表示する切り詰められたトレースが表示される場合がありました。

同期エラーとの主な違い

  • エラーは.then()コールバックやasync関数内でスローされる場合がある
  • スタックトレースにNode.js内部イベントループフレーム(processTicksAndRejectionsasyncRunEntryPoint)が含まれる場合がある
  • 並列Promiseを通じてエラーが伝播する場合、同じ根本原因から複数の未処理拒否が発生する可能性がある

防止策

  • Promiseチェーンには必ず.catch()を追加する
  • すべてのasync関数でtry/catchを使用する
  • グローバルハンドラーを追加: process.on('unhandledRejection', handler)
  • ESLintルールno-floating-promisesでコンパイル時にハンドラーの欠落を検出する

ユースケース

未処理のPromise拒否はプロセスをクラッシュさせる可能性があるため、Node.js本番サーバーでは重大な問題です。エラーログを監視する運用チームは、拒否の原因を素早く特定し、データベース接続、API呼び出し、またはファイルシステム操作のいずれに起因するかを判断する必要があります。

試してみる — Stack Trace Parser & Formatter

フルツールを開く