例外の実装方針

例外クラスの利用方針

Javaでの例外の利用方針は、思いつくもので大きく分けて3つ。

  • アプリケーション全体でひとつの例外クラスを利用
  • アプリケーション全体で複数の例外を利用
  • 検査例外を利用せず、全てRuntime Exceptionを利用
アプリケーション全体でひとつの例外クラスを利用

独自の例外をひとつだけ定義し、エラー内容はエラーコードで区別する。
EclipseのCoreExceptionなどがその例。

アプリケーション全体で複数の例外を利用

エラーの種類ごとにXXXException、YYYExceptionなどの独自例外を定義する。
独自例外にも継承関係を持たせて構造化したりもできる。
例外クラスの型を判定することで例外を区別できる。

検査例外を利用せず、全てRuntime Exceptionを利用

これは比較的最近のやり方のはず。検査例外を投げる場合、投げる例外クラスの変更や追加があると修正のインパクトが大きいのでRuntime Exceptionを利用する。
throwsには目印として投げるRuntime Exceptionを記述しておく。

エラーコード

他の言語同様に、Javaでもエラーコードの設計では普通に行う。
ただし、Eclipseのplugin開発などでは、提供されているCoreExceptionを利用したログ出力機構ではCoreExceptionに設定したエラーコードは出力されない。
このため、エラーコードをログファイルに出力する場合は、エラーメッセージ本文にコードを埋め込むなど工夫が必要。
ログファイルにはStackTraceが出力されるので、エラーコードを出す文化のないアプリケーションのプラグイン開発などでは無理に出さずにそのやり方に従うという選択もある。

例外を投げるタイミングとログ出力のタイミング

例外を投げるタイミングとログ出力のタイミングは必ずしも一致しない。
例外は発生元から、順次呼び出し元に伝播していくので、極端な話、各catch箇所で毎回StackTraceのログを出力していると、同じ内容が重複してログに出力されてしまう。
例外情報を詰めてThrowした場合は自分でログを出力しない、受けた例外をThrowしない場合はその時点でログ出力するというルールを適用すると重複は回避できる。
この場合、何かのバグでログ出力からもれてしまうケースがあるのではないか、漏れが発生するくらいなら重複覚悟で余計めに出力しておいたほうがよいのでは、と思ってしまうが、これはテストして漏れていないことを確認するしかないと思う。もしくはcriticalなエラーの場合は重複を許容して即座にログを出力してしまうとか。