C# 捕获所有超时异常并使用更多上下文将其记录到Elmah

C# 捕获所有超时异常并使用更多上下文将其记录到Elmah,c#,asp.net-mvc,elmah,C#,Asp.net Mvc,Elmah,我有多个使用ASP.NET MVC 4/5构建的web应用程序。他们都使用Elmah进行错误处理,我们的应用程序也会出现很多超时错误 以下是它的日志记录方式: 等待操作超时 System.ComponentModel.Win32异常 等待操作超时 我想在这个主题中记录一些更有意义的东西。类似于-DB Timeout-SP name的东西可能更有用,否则我必须打开每个日志,读取堆栈跟踪,然后进行调试 现在为了实现这一点,我知道我可以编写一个自定义异常,捕获所有db超时异常,并使用存储过程名称重新抛

我有多个使用ASP.NET MVC 4/5构建的web应用程序。他们都使用Elmah进行错误处理,我们的应用程序也会出现很多超时错误

以下是它的日志记录方式:

等待操作超时

System.ComponentModel.Win32异常

等待操作超时

我想在这个主题中记录一些更有意义的东西。类似于-DB Timeout-SP name的东西可能更有用,否则我必须打开每个日志,读取堆栈跟踪,然后进行调试

现在为了实现这一点,我知道我可以编写一个自定义异常,捕获所有db超时异常,并使用存储过程名称重新抛出自定义异常

但这需要我在每个服务层代码中编写相同的try-catch


有没有其他更好的方法可以解决这个问题?

可以通过ELMAH的错误过滤功能实现。我已经利用这个来解决这个问题了

简而言之,您需要挂接到ErrorLog_筛选事件中,请参见:

每当ELMAH想要在错误日志中记录错误时,就会调用此方法。如果存在HTTP上下文,并且抛出的异常是TimeoutException(仅以此为例),并且您需要将其替换为DB异常,那么我们将从抛出的异常中创建一个新错误。新错误会自动从抛出的错误中获取所有信息。通过Log方法记录新错误,并通过调用事件args上的disclease来消除带有错误消息的原始错误

void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs args)
{
    var httpContext = args.Context as HttpContext;
    if (httpContext != null && args.Exception is TimeoutException)
    {
        var error = new Error(args.Exception, httpContext);
        error.Message = "DB Timeout - SP name";
        ErrorLog.GetDefault(httpContext).Log(error);
        args.Dismiss();
    }
}