Skip to content

5.5 例外処理

コンパイルエラーでは検知できない、実行時に起こるエラー(ランタイムエラー・例外)を取り扱うための構文です。

エラーを意図的に発生させる(エラーを投げる)には、throw 文を使用します。

  • Error オブジェクト: 通常は new Error("エラーメッセージ") として作成したオブジェクトを投げます。
  • 挙動: throw 文が実行されると、そこでプログラムの実行が中断され、クラッシュ(強制終了)してエラーメッセージとスタックトレース(実行経路の履歴)が出力されます。

5.5.2 例外をキャッチするtry-catch文

Section titled “5.5.2 例外をキャッチするtry-catch文”

例外によるプログラムのクラッシュを防ぎ、エラー処理を行うための構文です。

  • 構文: try { ... } catch (err) { ... }
  • 処理の流れ: try ブロック内で例外が発生すると、即座に実行が中断され、catch ブロックへ処理が移行します。try 内で例外が起きなければ catch ブロックは無視されます。
  • エラーの受け取り: catch (err) の変数 err には、投げられた Error オブジェクトが入ります。

例外が持つ最大の特徴は、発生箇所から関数やブロックを無視して、呼び出し元の try-catch まで一気に制御を移す 大域脱出 にあります。

  • メリット: 深い階層の関数でエラーが起きても、呼び出し元の大元で1箇所にまとめてエラー処理を記述できる点です。
  • デメリットと型の問題: catch (err)err は型が予測できないため unknown 型となり、型システム上は少々扱いにくいという欠点があります。
  • 設計の指針: 場合によってエラー処理を細かく変えたい場合は、例外を使わず、関数の返り値として失敗を表す値(undefined や独自のエラー型)を返すアプローチのほうが、TypeScriptの型システムと相性が良く安全です。

try-catch の後に finally { ... } ブロックを追加することができます(catch を省略して try-finally とすることも可能)。

  • 挙動: エラーが起きたかどうかにかかわらず、何が何でも必ず実行される ブロックです。
  • 脱出への割り込み: 例外による大域脱出や、return 文による関数からの脱出が発生した際にも、その脱出に割り込んで必ず finally ブロックが実行されます。ファイルのクローズなど、必ず行わなければならない事後処理(クリーンアップ)に最適です。

コラム25 throwは何でも投げられる

Section titled “コラム25 throwは何でも投げられる”

throw 文は Error オブジェクトだけでなく、数値(throw 123;)や null など、どんな値でも投げることができます。

  • カスタムエラー: Error クラスを継承して class EmptyArrayError extends Error のような独自のエラークラスを作ると、catch 側で instanceof を使って特定のエラーだけを処理しやすくなります。
  • 特殊な用途: 最近のフロントエンド開発(ReactのSuspenseなど)では、大域脱出の性質を利用して「通信中の Promise オブジェクトを throw する」というアグレッシブな手法も登場しています。