例外メッセージをわかりやすくするためにContextedRuntimeExceptionクラスを使おう。

スポンサードリンク

概要

ContextedRuntimeExceptionクラスは、
ラベルと値のペアで付加情報を追加できます。

例外メッセージだけで状況を伝えるよりも、
わかりやすくスマートに書くことができます。

例外が発生したとき、スタックトレースなどで発生した場所は
簡単に特定することができます。
ただし、発生したときの状況や状態はスタックトレースではわからないので
メッセージなどが頼りになります。

そのメッセージも、通常の例外クラスでは1文字列しか受け取れないので
多くの情報を入れるのは難しいです。

try{
    //何らかの処理
}catch(Exception e){
    throw new RuntimeException("給与計算中に例外が発生。", e);
}

これでもなぜ例外になったかはわかりますが、
原因追及となると、もう少し状態がわかると便利です。

こんなときにContextedRuntimeExceptionクラスを使うと
こんなふうに書くことができます。

int employId = 1;
String name = "Taro";
int baseSalary = 300000;
 
try {
    // 何らかの処理
} catch (Exception e) {
    throw new ContextedRuntimeException("給与計算中に例外が発生。", e)
        .addContextValue("従業員ID", employId)
        .addContextValue("名前", name)
        .addContextValue("基本給", baseSalary);
}

このようにラベルと値のペアを簡単に追加できるので、
idなどの原因究明に必要な変数の値を追加しておけば、原因追及がグッと楽になります。

例外メッセージは次のように、出力されます。

org.apache.commons.lang3.exception.ContextedRuntimeException: 給与計算中に例外が発生。
Exception Context:
  [1:従業員ID=1]
  [2:名前=Taro]
  [3:基本給=300000]
---------------------------------
  at jp.tmkworks.sample.commons.exception.ContextedExceptionTest.test(ContextedExceptionTest.java:36)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  ... more

副作用もほぼないので、
今RuntimeExceptionを使っているところをContextedRuntimeExceptionに変えるだけで、
この機能を簡単に利用できます。

独自例外クラスを作るときもRuntimeExceptionではなくこちらを継承しておけば、
この機能を使いたいときにだけ使うことができます。

PR