Фон
Я розробляю 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]
атрибутом.