バックグラウンド
クライアント用のAPIサービスレイヤーを開発していて、すべてのエラーをグローバルにキャッチしてログに記録するように依頼されました。
したがって、不明なエンドポイント(またはアクション)のようなものは、ELMAHを使用するか、次のようなものをに追加することによって簡単に処理されGlobal.asax
ます。
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
。。ルーティングに関連しない.unhandledエラーはログに記録されません。例えば:
public class ReportController : ApiController
{
public int test()
{
var foo = Convert.ToInt32("a");//Will throw error but isn't logged!!
return foo;
}
}
また、[HandleError]
このフィルターを登録して、属性をグローバルに設定してみました。
filters.Add(new HandleErrorAttribute());
ただし、すべてのエラーがログに記録されるわけではありません。
問題/質問
/test
上記の呼び出しで生成されたようなエラーをインターセプトして、ログに記録するにはどうすればよいですか?この答えは明白であるように思われますが、私はこれまで考えられるすべてのことを試みました。
理想的には、要求しているユーザーのIPアドレス、日付、時刻など、いくつかをエラーログに追加したいと思います。また、エラーが発生したときにサポートスタッフに自動的にメールを送信できるようにしたいと考えています。エラーが発生したときにこれらのエラーをインターセプトできる場合にのみ、これらすべてを実行できます。
解決しました!
その答えを受け入れたDarin Dimitrovのおかげで、これを理解できました。 WebAPIは、通常のMVCコントローラーと同じ方法でエラーを処理しません。
これがうまくいきました:
1)名前空間にカスタムフィルターを追加します。
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is BusinessException)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(context.Exception.Message),
ReasonPhrase = "Exception"
});
}
//Log Critical errors
Debug.WriteLine(context.Exception);
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("An error occurred, please try again or contact the administrator."),
ReasonPhrase = "Critical Exception"
});
}
}
2)WebApiConfigクラスでグローバルにフィルターを登録します。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
config.Filters.Add(new ExceptionHandlingAttribute());
}
}
または、登録をスキップして、単一のコントローラーを[ExceptionHandling]
属性で装飾することもできます。