Ymirは例外ハンドリングの仕組みを提供しています。
例外ハンドラにはローカルハンドラとグローバルハンドラがあります。ローカルハンドラはPageクラス内で発生した例外をハンドリングするためのものです。グローバルハンドラはそれ以外の例外をハンドリングするためのものです。またグローバルハンドラはローカルハンドラの中で発生した例外もハンドリングすることができます。
ローカルハンドラはPageクラスが持つメソッドのうち@ExceptionHandlerアノテーションが付与されたものです。
@ExceptionHandlerアノテーションのvalue要素で例外型が指定されている場合は、そのメソッドは指定された型に対応するハンドラと見なされます。指定されていない場合は、メソッドがThrowableまたはそのサブクラスの引数を持つ場合、メソッドはその引数型に対応するハンドラと見なされます。引数を持たない場合はThrowable型に対応するハンドラと見なされます。
リクエストに対応するアクション毎にハンドラを分けたい場合は、@ExceptionHandlerアノテーションのactionName要素でアクション名を指定して下さい。アクション名が指定されない場合はそのメソッドは全てのアクションに関するハンドラメソッドと見なされます。
グローバルハンドラはルートパッケージ以下のhandlerサブパッケージ以下にある「<<例外クラス名>>Handler」という名前のクラスです。これらのクラスはシステムに自動的に認識されますのでコンポーネント登録は不要です。
例えばNullPointerExceptionのハンドラクラスの名前はNullPointerExceptionHandlerになります。グローバルハンドラに@ExceptionHandlerアノテーションを付与したメソッドを用意することで、そのメソッドが例外クラスがスローされた時に呼び出されます。
例外がスローされた場合、まずローカルハンドラが探索されます。例外クラスに完全に合致するハンドラがない場合は例外クラスの祖先クラスのハンドラが探索されます。見つからない場合はグローバルハンドラが探索されます。ページの処理でない箇所で例外がスローされた場合はローカルハンドラは探索されません。
以下の例では、それぞれ特定アクション用のローカルハンドラ、アクション共通のローカルハンドラ、グローバルハンドラが呼ばれるような例外を内部でスローしています。
MESSAGE