はじめに
Javaで開発していると、例外をキャッチして処理する場面はたくさん出てきます。しかし、ただ例外を捕まえて「新しい例外として投げ直す」だけでは、元々どんなエラーが発生したのか分からなくなってしまうことがよくあります。
そんなときに重要になるのが 例外チェーン(cause) です。
今回は、例外チェーン(cause)の使い方についてログとして記載していきたいと思います。
他にも、体系的にJavaを学びたい方には以下の教材がおすすめです:
👉スッキリわかるJava入門
👉スッキリわかるJava入門 実践編
例外チェーン(cause)とは?
例外チェーン(cause)とは、例外を再スローするときに「元の例外」を cause として保持する仕組みのことです。
例外チェーン(cause)を実施する例
第2引数に実際に発生した Exception を設定することで、「元の例外」を cause として保持できます。
try {
execute();
} catch (Exception e) {
// 第2引数に元のExceptionの内容も併せて設定
throw new RuntimeException("エラーが発生しました", e);
}
使わない場合の例
「元の例外」を cause を使用しない場合、何にExceptionでエラーが発生したかを握りつぶしてしまい、大元のExceptionがわからなくなってしまいます。
try {
execute();
} catch (Exception e) {
throw new RuntimeException("エラーが発生しました");
}
Throwable.getCause() の仕組み
causeの仕組みは、Javaの例外クラス Throwable によって実現されています。Throwable には次のような cause を管理するメソッドが存在し、例外チェーンでは、この内部フィールドに「元の例外オブジェクト」が格納されます。
Throwable getCause();
Throwable initCause(Throwable cause);
例外メッセージ例
以下のように、どこで何が発生したのかを階層的に追跡できるのが例外チェーンの最大の利点です。
Exception in thread "main" java.lang.RuntimeException: DB処理でエラーが発生しました
at com.example.App3.main(App3.java:31)
Caused by: java.io.FileNotFoundException: user.json (アクセスが拒否されました。)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:289)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:230)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:118)
at java.base/java.io.FileWriter.<init>(FileWriter.java:67)
at com.example.App3.main(App3.java:28)
まとめ
例外チェーン(cause)は、「例外の再スロー時に元の原因を失わないための仕組み」です。
単に例外を投げ直すだけでは情報が欠落してしまい、後から原因を追うことが非常に難しくなります。
例外チェーンを正しく使えば、以下のようなメリットがあります。
- cause を渡すだけで “原因の見える化” ができる
- 障害調査・デバッグ・保守が圧倒的に楽になる
- レイヤーごとの責務が明確になる
今後の開発では、cause を意識していきましょう。
ドキュメント
【公式ドキュメント】
Java SE Specifications (oracle.com)
最後に
Javaの環境構築は、この記事を参照してみてください。
【開発環境構築】VS CodeでJavaを使用するための環境構築を実施する – SEもりのLog (selifemorizo.com)
以上、ログになります。
これからも継続していきましょう!!


コメント