从Elmah错误邮件中过滤出已发出信号的异常

时间:2010-08-04 14:42:15

标签: asp.net elmah

我已经实现了一个围绕Elmah的错误信号的包装器方法,其中只有Elmah才能看到引发和邮寄的引发异常,但现在我只想过滤掉邮件中的这些信号异常,但仍然记录它们。我怎么能这样做?

这是我的简单包装器:

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

我想过将输入异常包装在一个自定义的SignalledException中,然后过滤掉那些不通过邮件的内容,但后来我的日志充满了SignalledExceptions,而不是真正的异常。

还有其他想法吗?

1 个答案:

答案 0 :(得分:3)

Elmah过滤主要用于异常类型。程序化过滤将允许我检查添加到异常的信息,但我还没有遇到具有ElmahFilteringData属性的异常类型,我更喜欢不“入侵”我想记录的异常。以下是我仅为某些信号异常发送电子邮件通知的方法:

首先,我有一个特殊的包装器异常,纯粹是为了告诉Elmah不要发送此类异常的电子邮件通知:

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) {}
}

然后,当我提出异常时,我通常只想记录而不是通过电子邮件发送,但有时可能通过电子邮件发送,我在异常记录服务中使用此代码:

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);
    }
}

现在,在Global.asax中的Elmah过滤器事件中,我解开了异常以记录它,如果它被包装,则将其从电子邮件通知管道中删除:

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();
    }
}