web-dev-qa-db-ja.com

global.asaxのApplication_ErrorがWebAPIのエラーをキャッチしない

私が取り組んでいるプロジェクトの場合、実装していることの1つは、古いASP.NETおよびMVCプロジェクトの一部のチームでコードを使用しているものです-Application_Error例外の経験と最も関連性のある詳細を記載した電子メールを開発チームに送信する例外キャッチャー。

外観は次のとおりです。

Global.asax:

protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    string path = "N/A";
    if (sender is HttpApplication)
        path = ((HttpApplication) sender).Request.Url.PathAndQuery;

    string args = string.Format("<b>Path:</b> {0}", path);

    // Custom code that generates an HTML-formatted exception dump
    string message = Email.GenerateExceptionMessage(ex, args);

    // Custom code that sends an email to the dev team.
    Email.SendUnexpectedErrorMessage("Some App", message);
}

ただし、「マイナーな」問題の1つです。このメカニズムをテストするために、意図的にコードの一部に例外をスローさせると...

public static void GetMuffinsByTopping(string topping)
{
    throw new Exception("Test Exception!", new Exception("Test Inner Exception!!!"));

    // Actual repository code is unreachable while this test code is there
}

フロントエンドJavaScriptはすぐにHTTP 500リクエストをインターセプトしていますが、上記のglobal.asax.csコードには到達していません(メソッドの最初の実行行にブレークポイントを設定します)。

質問:どのようにして「古い」_Application_Errorエラーメールを送信するハンドラ。これにより、チームの開発者はアプリケーションをより簡単にデバッグできますか?

34
Andrew Gray

エラー処理ロジックをApplication_Errorから独自の関数に抽象化します。 Web API例外フィルター を作成します。

//register your filter with Web API pipeline
GlobalConfiguration.Configuration.Filters.Add(new LogExceptionFilterAttribute());

//Create filter
public class LogExceptionFilterAttribute : ExceptionFilterAttribute 
{
    public override void OnException(HttpActionExecutedContext context)
    {
        ErrorLogService.LogError(context.Exception);
    }
}

//in global.asax or global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
    Exception ex = Server.GetLastError();
    ErrorLogService.LogError(ex);
} 

//common service to be used for logging errors
public static class ErrorLogService
{
    public static void LogError(Exception ex)
    {
        //Email developers, call fire department, log to database etc.
    }
}

Web APIからのエラーは、Application_Errorイベントをトリガーしません。ただし、例外フィルターを作成して登録し、エラーを処理できます。 ASP.NET Web API 2のグローバルエラー処理 も参照してください。

61
mason