1
votes

I'm trying to log with Elmah exceptions handled in try...catch blocks.

I have added a global handle error filter on Global.axax:

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

This is my ElmahHandledErrorLoggerFilter:

public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
    public void OnException(ExceptionContext context)
    {
        if (context.ExceptionHandled)
            ErrorSignal.FromCurrentContext().Raise(context.Exception);
    }
}

It will only log the Exception as in try{ ... }catch{ throw new Exception(); }. But that's not the problem, the problem is that I have a method with a try-catch called from the code already inside another try-catch. In this case although I put throw new Exception() inside the catch of the inner-method it doesn't log the exception, it goes back to the catch in the first method without logging the Exception. For example:

public void MainMethod()
{
    try
    {
        SecondMethod();
    }
    catch
    {
       ....second method jump here.....
    }
}

public void SecondMethod()
{
    try
    {
        int a =0;
        int b =;
        int result = b/a;
    }
    catch
    {
        throw new Exception();
    }
}

The exception thrown by SecondMethod is not being logged by Elmah. It goes back to the main method catch. If the main method catch also has a throw new Exception() code then it logs the exception. However it will be logged with the stack trace pointing to MainMethod and not to the SecondMethod.

What I wanted what was that every time it reaches a catch without rethrowing a new Exception, Elmah would log the exception. This is because I have many try-catch blocks in my application and I want to log these exceptions without manually logging on each try-catch. However if you tell me how can I log the exception from SecondMethod that would be fine.

1

1 Answers

1
votes

Are you using ASP MVC?

The filters will only execute for unhandled exceptions thrown from the controller methods. (The context.ExceptionHandled property tells you if it has been handled by another filter, not in a try-catch block). So if you swallow the exceptions in try-catch blocks inside your methods then they will not be handled by the error filters.

You need to decide when you want to manually handle the exceptions inside your code using try-catch blocks (and in that case manually log the exceptions with the aid of a base controller class or a helper class) or let the exception bubble and be handled by your filters. (You probably will want a mixture of the two, depending on each particular use case)

When you decide to rethrow the exceptions, take a look at this SO question. Basically you can rethrow an exception preserving the stack trace with:

try
{
    //code
}
catch (Exception ex)
{
    //...some error handling code here... 
    //Otherwise why the try-catch at all?
    throw;
}

You could do that in your sample MainMethod and the exception logged would preserve the stack trace.