Search code examples
c#asp.netfilterasp.net-web-apicustom-exceptions

Exception filter not triggered


I wanted to add the ExceptionFilter to my project at work. So i made a test api project with VS2013 on .net 4.5:

  1. A web api get action throws a custom exception (Has a filter attribute)

  2. Custom exception constructor being build

  3. Filter exception catch it and handles.

And it worked great!

Now, i went to my work project, which is working with .net 4.5, created a TestController file and copy paste the code from my test project file. The web Api action was hit, the custom exception constructor was called but the exception filter didn't triggered. Why?

This is my ApiController, ExceptionFilter, CustomException and some Customer class:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Mime;
using System.Text;
using System.Web.Http;
using System.Web.Http.Filters;
using System.Web.Services.Description;

namespace Web.Controllers.WebApi
{
    public class TestController : ApiController
    {
        public static List<Customer> Customers;
        static TestController()
        {
            Customers = new List<Customer>()
            {
                new Customer() {Id = 1, Name = "person1"},
                new Customer() {Id = 2, Name = "person2"},
            };
        }

    [ApiExceptionFilterAttribute]
    public IHttpActionResult Get(int id)
    {
        if (Customers != null)
        {
            var customer = Customers.FirstOrDefault(x => x.Id == id);
            if (customer == null)
            {
                throw new CustomerNotExistsException(id);
            }

            return Ok(customer);
        }

        return InternalServerError();
    }
}


public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}



public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        if (actionExecutedContext.Exception is CustomerNotExistsException)
        {
            throw new HttpResponseException(actionExecutedContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ((CustomerNotExistsException)actionExecutedContext.Exception).Message));
        }
        else
        {
            //genenral 500 error   

            //log exception
        }
    }
}



public class CustomerNotExistsException : HttpResponseException
{
    public int CustomerId { get; set; }
    public string Message { get; set; }

    private const string message = "customer id {0} not found";

    public CustomerNotExistsException(int customerId) : base(new HttpResponseMessage())
    {
        CustomerId = customerId;
        Message = string.Format(message, customerId);
    }

    public CustomerNotExistsException(int customerId, string message) : base(new HttpResponseMessage())
    {
        CustomerId = customerId;
        Message = message;
    }
}
}

This is my WebApiConfig:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}"
        ); 
    }
}

And this is my Global.asax

public class MvcApplication : HttpApplication
{

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        //BundleConfig.RegisterBundles(BundleTable.Bundles); 
    }

    void Application_Error(object sender, EventArgs e)
    {                        
        //some code here
    }

}

UPDATE:

Just realized that when the exception filter is not triggered i get status code 200!

Very strange since it throws an exception after all.


Solution

  • The solution that worked for me was to change the CustomException i created (CustomerNotExistsException in my code) to inherit from Exception base class and not from HttpResponseException.