リダイレクトではなく制御をカスタムエラーページに移す
前回の記事「未処理の例外への適切な対処法」で説明したように、「Web.config」の<customErrors>セクションの設定によって、未処理の例外が発生したときにユーザーフレンドリなカスタムエラーページを表示することができます。あいにく、ASP.NETランタイムは未処理の例外が発生したときにユーザーをカスタムエラーページに「リダイレクト」します。ランタイムが呼び出すResponse.Redirect(customErrorPageUrl)は、HTTPのステータスコード302をブラウザに送信するのですが、これは指定のURL(customErrorPageUrl)を要求せよという意味です。このリダイレクトは新たなWeb要求なので、未処理の例外を持っていた要求とは何の関連もありません。そのため、カスタムエラーページからServer.GetLastError()を呼び出すと、null値が返されます。
しかし、カスタムエラーページでエラーに関する情報を保持したいこともあります。おそらく、発生したエラーに応じたメッセージを表示したり、特定の役割を持つ認証された訪問者に例外の詳細を表示したいことがあるでしょう。これはErrorイベントハンドラ内でのServer.Transfer(customErrorPageUrl)の呼び出しによって達成できます。ドキュメントによれば、Server.Transfer(url)は「現在のページの実行を終了し、指定されたURLパスを使って新しいページの実行を開始」します。要するに、現在の要求の実行がサーバー上の別のページに委ねられるのです。クライアントに明示的なリダイレクトメッセージが返されることはなく、すべてがサーバー側で行われます。
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs) '... Email details of exception to developer ... Server.Transfer("~/SmartCustomErrorPage.aspx") End Sub
Server.Transfer()でコンテキストが維持されるので、カスタムエラーページではServer.GetLastError()を使って未処理の例外に関する情報を取得できます。ブラウザから見ると、コンテキストに変化はありません。つまり、ブラウザのアドレスバーには、Server.Transfer()された先のURLではなく、未処理の例外を発生させたページのURLが引き続き表示されるわけです。
この記事のダウンロードサンプルを使用すると、もっと高度なカスタムエラーページ(SmartCustomErrorPage.aspx)を表示できます。このエラーページは例外の詳細を調べて、発生した例外のタイプに応じてメッセージを組み立てます。
HTTPモジュールでErrorイベントを処理する
HTTPモジュールは、ASP.NETランタイムが発生させたイベントに応答できるマネージドコンポーネントです。代わりに、Errorイベントに応答するイベントハンドラをHTTPモジュール内に置くことができます。HTTPモジュールを使用することの利点は、HTTPモジュールアセンブリを「/bin」ディレクトリにドロップし、アプリケーションの「Web.config」に1行か2行の設定を追加するだけで既存のASP.NETアプリケーションに追加できる「プラグ可能な」コンポーネントを提供することにあります。
エラー処理のためにHTTPモジュールを作成し設定するのは本稿の守備範囲を超えるので、ここで説明することはできません。代わりに、Atif Azizが提供しているフリーなオープンソースライブラリ、ELMAH(Error Logging Modules And Handlers)をお勧めします。ELMAHは、未処理の例外をデータストアに記録するためのHTTPモジュールと、例外の詳細をWebページまたはRSSフィードに表示するためのHTTPハンドラから成ります。
ELMAHは、GotDotNet Workspaceからダウンロードできます。ELMAHのセットアップとインストールの詳細については、「Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components」を参照してください。ELMAHのセットアップに要する時間は60秒くらいです。これにより、例外の詳細な記録、開発者への充実した通知、および例外の詳細をオンラインで見られるユーザーフレンドリなWebページが提供されます。ぜひ試してください。
まとめ
Webアプリケーションで未処理の例外が発生した場合、通常はエンドユーザーにユーザーフレンドリなカスタムエラーページが表示され、例外の詳細が「処理」されるようにしたいと思うでしょう。例外をどのように処理するかはアプリケーションごとに違ってくるでしょうが、通常は例外を記録し、開発者に通知します。前回の記事「未処理の例外への適切な対処法」では、カスタムエラーページの表示方法を説明し、今回の記事では、アプリケーションのErrorイベントのためのイベントハンドラの作成方法を説明しました。
例外の記録と通知を行うシステムを独自に作成するよりも、フリーなオープンソースライブラリのELMAHを試してみるようお勧めします。ELMAHには、未処理の例外を記録するためのHTTPモジュールと、例外の詳細を電子メールで送るためのオプションが含まれています。
それでは、ハッピープログラミング!
参考資料
- Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components
- ELMAH GotDotNet Workspace(ここからELMAHのコードをダウンロードできる)
