Задний план
Я разрабатываю сервисный уровень 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]
атрибутом.