Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Web API IExceptionLogger doesn't catch exceptions

I'm trying to setup a global exception handler as outlined here: Web API Global Error Handling. I"ve setup a case where an exception gets thrown within a controller constructor. But my exception isn't getting logged. Instead WebApi is just returning the exception and full stack trace to the calling client as a JSON message.

I don't know if it matters, but my controllers actions are using async / await like this:

[HttpGet, Route("GetLocationNames")]
public async Task<IEnumerable<String>> Get()
{
    return await adapter.GetLocationNames();
}

I have the following implementation:

using log4net;
using System.Threading.Tasks;
using System.Web.Http.ExceptionHandling;

namespace warehouse.management.api
{
    public class Log4NetExceptionLogger : ExceptionLogger
    {
        private ILog log = LogManager.GetLogger(typeof(Log4NetExceptionLogger));

        public async override Task LogAsync(ExceptionLoggerContext context, System.Threading.CancellationToken cancellationToken)
        {
            log.Error("An unhandled exception occurred.", context.Exception);
            await base.LogAsync(context, cancellationToken);
        }

        public override void Log(ExceptionLoggerContext context)
        {
            log.Error("An unhandled exception occurred.", context.Exception);
            base.Log(context);
        }

        public override bool ShouldLog(ExceptionLoggerContext context)
        {
            return base.ShouldLog(context);
        }
    }
}

And I'm registering it like this:

using Owin;
using System.Web.Http;
using System.Web.Http.ExceptionHandling;

namespace warehouse.management.api.Config
{
    public static class WebApiConfig
    {

        public static IAppBuilder RegisterApiConfig(this IAppBuilder app, HttpConfiguration config)
        {
            config.MapHttpAttributeRoutes();
            config.Services.Add(typeof(IExceptionLogger), new Log4NetExceptionLogger());
            return app;
        }
    }
}

And here's my packages.conf:

<?xml version="1.0" encoding="utf-8"?>
<packages>
    <package id="log4net" version="2.0.3" targetFramework="net45" />
    <package id="Microsoft.AspNet.WebApi.Client" version="5.1.2" targetFramework="net45" />
    <package id="Microsoft.AspNet.WebApi.Core" version="5.1.2" targetFramework="net45" />
    <package id="Microsoft.AspNet.WebApi.Owin" version="5.1.2" targetFramework="net45" />
    <package id="Microsoft.AspNet.WebApi.WebHost" version="4.0.20505.0" targetFramework="net45" />
    <package id="Microsoft.Owin" version="2.1.0" targetFramework="net45" />
    <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
    <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" />
    <package id="Owin" version="1.0" targetFramework="net45" />
    <package id="Unity" version="3.5.1404.0" targetFramework="net45" />
    <package id="Unity.AspNet.WebApi" version="3.5.1404.0" targetFramework="net45" />
    <package id="WebActivatorEx" version="2.0" targetFramework="net45" />
</packages>
like image 659
Mark J Miller Avatar asked May 29 '14 16:05

Mark J Miller


1 Answers

Turns out it was the ordering. In my startup class (not shown) I moved the call to my RegisterApiConfig method (above, in the OP) to before my call to UseWebApi and now it works.

like image 80
Mark J Miller Avatar answered Sep 17 '22 12:09

Mark J Miller