Java

【Java】catch句で例外が発生した場合の書き方【addSuppressed】

こんにちは、ともです。

今回はcatch句で例外が発生した際の処理の書き方について書きます。

catch句の中で例外が発生し、その例外をそのままthrowしてしまうとtry句で発生した例外が闇に葬られてしまいますよね。

その場合の書き方について記事を書きます。結論としてはaddSuppressedしよう。

ThrowableクラスのaddSuppressedを確認していただければ詳細分かります。

catch句で例外を投げる状況

package blog1;

/**
 * try句の例外が消えてしまうサンプル
 * @author tomo
 */
public class Test {

	/**
	 * 例外をcatchしStackTraceを表示するメソッド
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			doMethod();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * catch句で例外をthrowするメソッド
	 * @throws Exception
	 */
	private static void doMethod() throws Exception {
		try {
			throw new Exception("throw in try");
		} catch(Exception e) {
			throw new Exception("throw in catch");
		}
	}
}

doMethodのtry句で例外が発生しています。

しかし、catch句でも例外が発生してしまいました。

この場合mainメソッドでcatchする例外はcatch句で発生した例外になります。

よって、printStackTraceの値はjava.lang.Exception: throw in catchとなります。つまりtry句で発生した例外原因が消えてしまいました。

これでは本当の原因例外が分かりませんね。

addSuppressed使おう

addSuppressedで原因例外を残しましょう。

suppressed(抑圧された)という意味です。つまりtry句の例外は抑圧されてしまった訳です。その抑圧された例外を追加するメソッドがaddSuppressedです。

下記のようなコードを書きました。

package blog1;

/**
 * try句の例外が消えてしまうサンプル
 * @author tomo
 */
public class Test {

	/**
	 * 例外をcatchしStackTraceを表示するメソッド
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			doMethod();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * catch句で例外をthrowするメソッド
	 * @throws Exception
	 */
	private static void doMethod() throws Exception {
		try {
			throw new Exception("throw in try");
		} catch(Exception expInTry) {
			Exception expInCatch = new Exception("throw in catch");
			expInCatch.addSuppressed(expInTry);
			throw expInCatch;
		}
	}
}

addSupprssedメソッドでtry句内で発生した、抑圧されてしまう例外を追加してあげます。追加後に例外をthrowします。

そうすると下記のようなprintStackTraceとなります。

java.lang.Exception: throw in catch
	at Blog/blog1.Test.doMethod(Test.java:28)
	at Blog/blog1.Test.main(Test.java:15)
	Suppressed: java.lang.Exception: throw in try
		at Blog/blog1.Test.doMethod(Test.java:26)
		... 1 more

原因例外も残っていますね。これで問題箇所の特定が可能になります。

めでたし、めでたし。