2

I am using ELMAH to try and log handled exceptions (ones that occur in try catches). However I am unable to get ELMAH to log any exceptions which occur in a try catch.

Here is my action:

    [ValidateAntiForgeryToken]       
    public async Task<ActionResult> Login(LoginViewModel model) {

        try {
            throw new Exception("Log me elmah");
        }
        catch (Exception e) {
            ModelState.AddModelError("", "Something unexpected happened, please try again.");
            return View(model);
        }
    }

I have followed advice both from here: https://docs.elmah.io/elmah-and-custom-errors/ and here: How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?

But my ElmahExceptionLogger is only getting triggered for unhandled exceptions.

Here is my ElmahExceptionLogger:

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

Here is my global.asax:

  public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);        
        }      
    }

Here is my register global filters method:

 public class FilterConfig {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
            filters.Add(new ElmahExceptionLogger());
            filters.Add(new HandleErrorAttribute());



            /*Append no cache to all actions in all controllers so we don't cache any pages, I dont particularly like it because it means an increased server load
            However there are reasons to this; The first being data gets updated regularly and we want users to have the most up-to-date data
            And also you can press back after logging out to get to the cached page before. It can be overridden per action if needed */
            filters.Add(new OutputCacheAttribute {
                VaryByParam = "*",
                Duration = 0,
                NoStore = true
            });
        }
    }

Does anyone know how to get ELMAH to log my exceptions in try catches?

ThomasArdal
  • 4,999
  • 4
  • 33
  • 73
Andrew
  • 720
  • 3
  • 9
  • 34

2 Answers2

3

Of course it's only getting triggered for unhandled exceptions. Those filters only run for errors that are allowed to bubble up (meaning, unhandled). If you want to log a handled exception, then you need to put that ErrorSignal.FromCurrentContext().Raise() logic inside of your catch block.

catch (Exception e)
{
    ModelState.AddModelError("", "Something unexpected happened, please try again.");
    ErrorSignal.FromCurrentContext().Raise(e);
    return View(model);
}

If you find yourself doing this a lot, then I suggest you switch off using Elmah. Elmah isn't a general logging framework, it's geared for unhandled errors. It would be better to use a logging system such as Serilog or Nlog and then have those log to a specialized system such as Seq.

mason
  • 31,774
  • 10
  • 77
  • 121
  • I understand that, but I was wondering if there was an automatic way of logging an unhandled exception – Andrew May 03 '18 at 16:46
  • @Andrew You're confusing the two. This isn't an unhandled exception, because you haven't allowed it to bubble up. You've handled it. – mason May 03 '18 at 16:47
  • Sorry, It was a typo. I mean is there a way of logging the handled exception automatically. But I guess not, thank you for your response – Andrew May 03 '18 at 16:48
  • @Andrew No, there wouldn't be, because you've *caught* the exception. If you're catching it, then the only code that's going to run for it would be within the catch block, unless you choose to rethrow it. And rethrowing something you've taken care of isn't really a good idea. – mason May 03 '18 at 16:49
  • 1
    @Andrew I added a paragraph at the bottom of my question about a better way of logging these sorts of things. – mason May 03 '18 at 16:50
0

While not exactly "automatic" here is an approach I took to at least make logging easier in Try-Catch blocks.

I first created an extension to the Exception class:

    Imports Elmah
    Imports System
    Imports System.Web
    Imports System.Runtime.CompilerServices


Public Module ElmahExtension

    <Extension()>
    Public Sub LogToElmah(ex As Exception)


        If HttpContext.Current Is Nothing Then

            ErrorLog.GetDefault(Nothing).Log(New [Error](ex))
            Dim req = New HttpRequest(String.Empty, "https://YOURWEBSITE", Nothing)
            Dim res = New HttpResponse(Nothing)
        Else
            ErrorSignal.FromCurrentContext().Raise(ex)
            ErrorLog.GetDefault(HttpContext.Current).Log(New [Error](ex))
        End If
    End Sub
End Module

To use it you can do this:

   Try

      YOUR CODE HERE

  Catch
      ex.LogToElmah()
  End Try

This will pass the exception object to ELMAH and log the error.

So not quite automatic, but easier. Especially, if you use something like ReSharper to create a code shortcut with the "ex.LogToELMAH" included.

DevMedic
  • 1
  • 4