Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ELMAH and API controller in MVC4 not logging errors

Using an API controller in MVC4, when the controller action throws an exception, ELMAH does not log the error.

I think the problem is that MVC4 sets the HTTP status code to 500, and it returns the exception details in a JSON object, but it does not throw an unhandled exception so ELMAH never sees it.

How can I get ELMAH to capture all responses where the status code is not 200?

like image 963
Greg Ennis Avatar asked Apr 08 '12 00:04

Greg Ennis


2 Answers

The anwser described before doesn't work. I've tried on my test server and received an error ("The given filter instance must implement one or more of the following filter interfaces: IAuthorizationFilter, IActionFilter, IResultFilter, IExceptionFilter.")

Then I realized what happened .... you are trying to add the custom filter to the MVC Global Filter (filters.Add(new ElmahHandledErrorLoggerFilter());)

To fix that, I've split the filter registration in GlobalFilter and HttpFilter

FilterConfig.cs

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
    }

    public static void RegisterHttpFilters(HttpFilterCollection filters)
    {
        filters.Add(new ElmahHandledErrorLoggerFilter());
    }

Global.asax

    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    FilterConfig.RegisterHttpFilters(GlobalConfiguration.Configuration.Filters);

;-)

like image 74
julianox Avatar answered Nov 02 '22 22:11

julianox


UPDATE: This answer does not work in latest versions. Use julianox's answer.

Answer found from information here: http://www.asp.net/web-api/overview/web-api-routing-and-actions/exception-handling

Where the exception filter logs to elmah:

public class ElmahHandledErrorLoggerFilter : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext actionExecutedContext)
    {
        base.OnException(actionExecutedContext);

        ErrorSignal.FromCurrentContext().Raise(actionExecutedContext.Exception);
    }
}

but you also have to add the error filter to the GlobalConfiguration filters:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        GlobalConfiguration.Configuration.Filters.Add(new ElmahHandledErrorLoggerFilter());
        filters.Add(new ElmahHandledErrorLoggerFilter());
        filters.Add(new HandleErrorAttribute());
    }
like image 44
Greg Ennis Avatar answered Nov 02 '22 22:11

Greg Ennis