I have a ASP WebAPI project. I'm trying to setup a global exception handler on my basecontroller. So I created an ExceptionFilterAttribute
like so.
using System.Web.Http.Filters;
public class MyExceptionFilterAttribute : ExceptionFilterAttribute
{
protected static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
public override void OnException(HttpActionExecutedContext actionExecutedContext)
{
var exception = actionExecutedContext.Exception;
log.Fatal(exception);
base.OnException(actionExecutedContext);
}
}
Then I also registered it in /App_Start/WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// ...
// Setup Filters
config.Filters.Add(new MyExceptionFilterAttribute());
}
}
When I add the attributes to my controller (or base-controller), nothing gets logged. What am I doing wrong?
Edit: My controller throwing the exception:
[HttpGet]
public string Hello(string name)
{
if (name.Equals("error", StringComparison.OrdinalIgnoreCase))
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
else
{
return name;
}
}
Global Exception Filters With exception filters, you can customize how your Web API handles several exceptions by writing the exception filter class. Exception filters catch the unhandled exceptions in Web API. When an action method throws an unhandled exception, execution of the filter occurs.
In the Design tab part of the Ribbon, select New > Global Handler. The New Global Handler window opens. Type in a Name for the handler and save it in the project path. Click Create, a Global Exception Handler is added to the automation project.
Use the UseExceptionHandler middleware in ASP.NET Core So, to implement the global exception handler, we can use the benefits of the ASP.NET Core build-in Middleware. A middleware is indicated as a software component inserted into the request processing pipeline which handles the requests and responses.
Actually when you add that filter to your HttpConfiguration
it means that it will be executed for any action. That is, you don't need to add the whole attribute to your API controllers.
What can be skipping your filter? Other filter. The first filter to set the response wins and it can happen that the action itself gets never executed.
Anyway, maybe you need to switch to implement an IExceptionHandler
and configure it as follows:
config.Services.Replace(typeof(IExceptionHandler), new MyExceptionHandler());
This approach is better because it's a true last-chance exception handler and it will be always called independently of the behavior of filters.
Like @ShekharPankaj had pointed out, not all exceptions are handled by the attribute (or the approach @Matías provided). My code was fine. I simple changed the exception to a ArgumentException
and it gets handled.
See also this SO-thread: catch all unhandled exceptions in ASP.NET Web Api
To answer my own question, this isn't possible!
Handling all exceptions that cause internal server errors seems like a basic capability Web API should have, so I have put in a request with Microsoft for a Global error handler for Web API:
https://aspnetwebstack.codeplex.com/workitem/1001
If you agree, go to that link and vote for it!
In the meantime, the excellent article ASP.NET Web API Exception Handling shows a few different ways to catch a few different categories of error. It's more complicated than it should be, and it doesn't catch all interal server errors, but it's the best approach available today.
Update: Global error handling is now implemented and available in the nightly builds! It will be released in ASP.NET MVC v5.1. Here's how it will work: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With