Фон
Я разрабатываю уровень обслуживания API для клиента, и мне было предложено поймать и зарегистрировать все ошибки по всему миру.
Итак, хотя что-то вроде неизвестной конечной точки (или действия) легко обрабатывается с помощью ELMAH или добавлением чего-то вроде этого в Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
.,. Необработанные ошибки, не связанные с маршрутизацией, не регистрируются. Например:
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-адрес запрашивающего пользователя, дата, время и т.д. Я также хочу иметь возможность автоматически отправлять сотрудникам службы поддержки автоматически при возникновении ошибки. Все это я могу сделать, если только я могу перехватить эти ошибки, когда они произойдут!
РЕШЕНО!
Благодаря Дарину Димитрову, чей ответ я принял, я понял это. 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]
.