Question

I've implemented a wrapper method around Elmah's Error Signaling, where a raised exception is only seen by Elmah for logging and mailing, but now I'd like to filter only these signalled exceptions out of the mailing, but still log them. How can I do this?

This is my simple wrapper:

    public void LogException(Exception exception)
    {
        ErrorSignal.FromContext(HttpContext.Current).Raise(exception);
    }

I've thought of wrapping the input exception in a custom SignalledException, and filtering those out of mailing, but then my logs get full of SignalledExceptions, and not the real exceptions.

Any other ideas please?

Was it helpful?

Solution

Elmah filtering works mainly on exception types. Programmatic filtering would allow me to examine information added to an exception, but I have yet to come across an Exception type with an ElmahFilteringData property, and I prefer not to 'invade' the exceptions I want logged. Here is how I accomplished only sending email notificatins for certain signalled exceptions:

First I have a special wrapper exception, purely for telling Elmah not to send an email notification for exceptions of this type:

public class ElmahEMailBlockWrapperException: Exception
{
    public const string Explanation = "This is a wrapper exception that will be blocked by Elmah email filtering.  The real exception is the InnerException";
    public ElmahEMailBlockWrapperException(Exception wrappedException):base(Explanation, wrappedException) {}
}

Then, when I raise an exception I normally only want logged and not emailed, but maybe sometimes emailed, I use this code in my exception logging service:

public void LogException(Exception exception, bool includeEmail)
{            
    if (includeEmail)
    {
        ErrorSignal.FromContext(HttpContext.Current).Raise(exception);
    }
    else
    {
        // Wrap the input exception in a special exception type that the Elmah email filter can block.
        var wrappedException = new ElmahEMailBlockWrapperException(exception);
        ErrorSignal.FromContext(HttpContext.Current).Raise(wrappedException);
    }
}

Now, in the Elmah filter events in Global.asax, I unwrap the exception to log it, and if it is wrapped, dismiss it from the email notification pipeline:

public void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e)
{
    // If the exception was wrapped in a ElmahEMailBlockWrapperException exception to be blocked by the ErrorMail filter, the InnerException 
    // of the the ElmahEMailBlockWrapperException is the real exception to be logged, so we extract it, log it, and dismiss the wrapper.
    var ebw = e.Exception.GetBaseException() as ElmahEMailBlockWrapperException;
    if (ebw != null)
    {
        ErrorLog.GetDefault(HttpContext.Current).Log(new Error(ebw.InnerException));
        e.Dismiss();
    }
}

public void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e)
{
    // If the exception was wrapped, i.e. raised only to be logged by Elmah and not emailed, dismiss it.
    if (e.Exception.GetBaseException() is ElmahEMailBlockWrapperException)
    {
        e.Dismiss();
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top