システムエラーへの対処法
システムエラーへの対処は、正常系の流れとは違う例外的なケースなので、必然的に.NET Frameworkの例外処理を使うことになります。
.NET Frameworkの例外処理
システムエラーが発生した際、何らかの「例外(Exception)」がスローされます。例外を処理するには、.NET Frameworkではtry-catch構文が一般的です。
しかし、try-catch構文では各イベントハンドラーにそれぞれ記載する必要があり、冗長感は否めません。また、別々に処理を書くということは、例外を握りつぶしてしまうなど、バグが入り込む余地が残されており、アプリケーションで統一した挙動を保証できなくなってしまいます。
この問題を解決するため、.NET Frameworkには「集約例外ハンドラー」という仕組みが用意されています。集約例外ハンドラーは今回の連載で扱っているASP.NETだけでなく、コンソールアプリケーション、Windowsフォームアプリケーション、WPFアプリケーション、Windowsサービスアプリケーションなど、あらゆるアプリケーションで使用できます。
ただし、集約例外ハンドラーを利用する具体的な方法については統一されていませんので、実装するアプリケーションごとにやり方をMSDNライブラリなどで確認してください。
今回はASP.NETで集約例外ハンドラーを利用するやり方について説明します。
集約例外ハンドラー
ASP.NETの集約例外ハンドラーには、発生した例外を補足する箇所の違いで、アプリケーションレベル、ページレベルの2種類あります。
[1] アプリケーションレベルの集約例外ハンドラー
アプリケーションレベルの集約例外ハンドラーは、「グローバル アプリケーション クラス(Global.asaxファイル)」を用いて、Application.Errorイベントハンドラーを実装します。
void Application_Error(object sender, EventArgs e) { var ex = Server.GetLastError(); // (1) Logger.WriteError(ex); // (2) }
(1) 発生した例外を取得する
発生した例外を取得するには、Server.GetLastError()メソッドを使用します。
(2) 発生した例外の情報を処理する
イベントログやログファイルなどに発生した例外の内容を出力します。
出力する情報に他に付加すべき内容があれば自由に追加してください。
例外情報の出力で良くありがちなのが「発生した機能名も出力したい」といったケースです。これについては、.NET Frameworkの例外機構はスタックトレースという仕組みを持っていて、例外が発生した箇所の詳細が標準の仕組みで確認可能です。従って、各アプリケーションで独自に機能名を埋め込むなどの処理は不要です。
基本的にはアプリケーションレベルで十分だとは思いますが、ページごとに何らかのクリーンアップ処理が必要であるなどの特殊な理由があれば、ページレベルの処理を行っても良いでしょう。
[2] ページレベルの集約例外ハンドラー
ページレベルの集約例外ハンドラーは、Page.Errorイベントハンドラーです。発生した例外の取得方法などは、Application.Errorイベントハンドラーと同じです。
なお、発生した例外はページレベルの集約例外ハンドラーで例外を処理した後も、そのままアプリケーションレベルの集約例外ハンドラーでも捕捉されますので注意が必要です。