Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I log exceptions thrown during dependency resolution in my Web API project?

How do I set up my Web API 2 (version 5) project hosted in IIS to log an error if dependency resolution for a controller fails? I'm using the Autofac Web API 2 integration (version 3.1) for DI.

In my Global.asax.cs I have the following:

public class Global : HttpApplication {
    protected void Application_Start() {
        var resolver = new AutofacWebApiDependencyResolver(_container);
        GlobalConfiguration.Configuration.DependencyResolver = resolver;

        // other initialization

        GlobalConfiguration.Configuration.EnsureInitialized(); 

    }

    protected void Application_Error(Object sender, EventArgs e){
        Exception exception = Server.GetLastError();
        if (exception != null) {
            _log.Error("Application error", exception);
        }
    }
}

In a similar MVC project using AutofacDependencyResolver this suffices to log the Autofac.Core.DependencyResolutionException thrown when Autofac can't resolve a dependency while creating a controller, but in my Web API project this doesn't seem to work, either the exception isn't thrown or I don't have the correct logging handler set up. Instead no message is logged an a 500 response is returned to the client.

If no errors are thrown during dependency resolution (my module is set up correctly) then everything works fine, the controller is resolved and handles the request as expected.

I also have a couple other exception loggers set up that also don't log this exception:

  • Handling the unhandled exception event: AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException (in Global.asax.cs)
  • Setting up an exception logging filter deriving from ExceptionFilterAttribute. This logs exceptions thrown while the controller is handling the request but not this one thrown during dependency resolution.
like image 727
Lawrence Johnston Avatar asked Mar 21 '23 22:03

Lawrence Johnston


1 Answers

This can be done in Web API 2.1 by using the new Global Error Handling.

public class Log4NetExceptionLogger : ExceptionLogger {
    private static readonly ILog _log = LogManager.GetLogger("{your logger name here}");
    public override void Log(ExceptionLoggerContext context) {
        if (context == null) {
            throw new ArgumentNullException("context");
        }
        // When the framework calls an exception logger or an exception handler, it will always provide an Exception and a Request.
        // http://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling&referringTitle=Specs
        if (context.Exception == null) {
            throw new ArgumentException("context.Exception is null", "context");
        }
        if (context.Request == null) {
            throw new ArgumentException("context.Request is null", "context");
        }

        _log.Error(context.Request, context.Exception);
    }
}

// In GlobalConfiguration setup in Global.asax.cs
config.Services.Add(typeof(IExceptionLogger), new Log4NetExceptionLogger());
like image 169
Lawrence Johnston Avatar answered Apr 06 '23 19:04

Lawrence Johnston