LoginSignup
34
22

More than 5 years have passed since last update.

Nodeのエラーハンドリング(unhandledRejectionとuncaughtException)について

Last updated at Posted at 2018-07-04

はじめに

基本的にはNode.js v10.5.0 Documentationの該当箇所を意訳して個人的な備忘録として残そうとしているだけです。

uncaughtException

process.on('uncaughtException', (err) => {
  fs.writeSync(1, `Caught exception: ${err}\n`);
});
  • どこにもキャッチされずにprocessまで来てしまったエラーをキャッチ。
  • NodeJSのデフォルト(上記のようにハンドリングしない場合)では、このようなエラーはスタックトレースに出力して終了。
  • リスナーの関数はerrだけ。

注意点

  • このハンドリングでエラーがcatchされた場合、処理を継続すべきではない。
    • 完全に想定外の状態になっていることを意味しているので、ここから無理やり復帰しようとして更なるエラーが起きる可能性がある。
    • 例えるなら「コンピュータのアップグレード時にコンセントを抜くようなもの」。その意は「10回中9回は問題ないかもしれないが、1回はシステム破壊が起きる」。
  • ハンドリング内の処理でさらにエラーが発生した場合は、0以外の終了コードで終了する。
    • 無限ループを避けるため。
  • 正しい使い方は「プロセス終了前にクリーンアップを実行する」という目的で使うこと。

unhandledRejection

  • reason: <Error> | <any> 基本的にはObject
  • p: Promise<any> rejectされたPromise
process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at:', p, 'reason:', reason);
  // application specific logging, throwing an error, or other logic here
});
  • unhandledRejectionはPromiseがrejectされた時にいつでも発行される。
  • 普通はpromise.catch()とかasync/awaitだとtry-catchでキャッチされるが、どこにもキャッチされなかった場合に呼ばれる。
  • どのpromiseでrejectされたのかを追跡する(try-catchを入れ忘れている箇所の特定)のに役立つ。

まとめ

  • uncaughtExceptionは、もし使う場合にはそこから処理を継続するのはやめましょう。
  • 「try-catch入れ忘れちゃうよね!!」という私みたいな人はunhandledRejectionを設定しておきましょう。

【備忘録】ブラウザで使う場合

promiseの例外キャッチ用にunhandledRejectionを加えて、それ以外の例外キャッチ用に以下を加えておく。

window.addEventListener( "error", ( e ) => {
    // todo エラー処理
} );
34
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
22