【Java】例外チェーンの最下層のCauseを取得する

■概要

擬似的に3階層Exceptionを作成し、最終階層のCauseをループ処理を使用して取得する。

ループ処理を使用することで、安全に最下層のCauseを取得できる。
※Exception.getCause().getCause().getCause()・・・と指定すれば、何階層でも取得することは可能だが、2階層のException対して.getCause().getCause()・・・と指定してしまうとNullとなり、場合によっては「NullPointerException」が発生する原因となるので注意

今回は、以下のような階層のExceptionを作成する。

Exception top
 └→ getCause() → level1 (RuntimeException)
      └→ getCause() → level2 (IllegalArgumentException)
           └→ getCause() → level3 (IOException)
                └→ getCause() → null ここが4階層目

■サンプルコード

サンプルコードでは、比較として「getCause()」を列挙した場合のものも記載する。

import java.io.IOException;

public class ExceptionChainMain {

  /**
   * 最下層のCause取得処理
   *
   * @param throwable: 例外
   * @return: 最下層のCause
   */
  public static Throwable getRootCause(Throwable throwable) {
    Throwable cause = throwable;

    // 次の階層のcauseがnullになるまで繰り返し
    while (cause.getCause() != null) {
      // 次のcauseをセット
      cause = cause.getCause();
    }
    return cause;
  }

  public static void main(String[] args) {
    // 4段階の例外チェーンを構築
    // Exception -> RuntimeException -> IllegalArgumentException -> IOException
    IOException ioException = new IOException("Disk failure");
    IllegalArgumentException illegalArgumentException = new IllegalArgumentException(
        "Invalid argument", ioException);
    RuntimeException runtimeException = new RuntimeException("Runtime wrapper",
        illegalArgumentException);
    Exception topException = new Exception("Top level exception", runtimeException);

    // 1回 getCause()
    Throwable cause1 = topException.getCause();
    System.out.println("1st cause: " + cause1);

    // 2回 getCause()
    Throwable cause2 = topException.getCause().getCause();
    System.out.println("2nd cause: " + cause2);

    // 3回 getCause()
    Throwable cause3 = topException.getCause().getCause().getCause();
    System.out.println("3rd cause: " + cause3);

    // 4回 getCause(): null
    Throwable cause4 = topException.getCause().getCause().getCause().getCause();
    System.out.println("4rd cause: " + cause4);

    // 最下層のcauseを呼び出し
    System.out.println("最下層 cause: " + getRootCause(topException));
  }
}

■実行結果

1st cause: java.lang.RuntimeException: Runtime wrapper
2nd cause: java.lang.IllegalArgumentException: Invalid argument
3rd cause: java.io.IOException: Disk failure
4rd cause: null
最下層 cause: java.io.IOException: Disk failure

コメント

タイトルとURLをコピーしました