使用NLog处理错误并尝试捕获

Pat*_*ick 8 c# error-handling asp.net-mvc elmah nlog

我使用NLog在我的操作中记录错误以存储包含其他信息的错误,例如:

using NLog;

private static Logger _logger = LogManager.GetCurrentClassLogger();

public virtual ActionResult Edit(Client client)
{
  try
  {
        // FORCE ERROR
        var x = 0;

        x /= x;

        return RedirectToAction(MVC.Client.Index());
  }
  catch (Exception e)
  {
    _logger.Error("[Error in ClientController.Edit - id: " + client.Id + " - Error: " + e.Message + "]");
  }
}
Run Code Online (Sandbox Code Playgroud)

我在Web.config中配置了错误处理:

<customErrors mode="On" />
Run Code Online (Sandbox Code Playgroud)

但是当我执行Action(页面保留在同一个地方)时,我没有被重定向到Error.cshtml,为什么?

我可以用Elmah做同样的事情吗?(记录客户端ID等附加信息)

Mik*_*kis 6

首先,大多数人通过捕获异常来解决这个错误。这样,异常就会传播到 ASP.NET,后者会显示“500 内部错误”网页,记录所有相关信息。

  • 如果您的服务器配置为生产,则错误页面只会显示“发生错误,已记录详细信息”。

  • 如果服务器配置为开发,那么您将获得著名的黄页,其中包含异常类型、消息和堆栈跟踪。

吞掉异常并手动重定向到错误页面是一种不好的做法,因为它隐藏了错误。有一些工具可以检查您的日志并为您提供良好的统计数据,例如有关成功/失败请求的百分比,但这些工具将不再起作用。

所以,不接受例外是人们所做的,至少它解决了你的问题。


现在,我发现这非常笨重,因为我不喜欢手动查找黄页中提到的源文件并手动转到提到的行号。我实际上对黄页没有任何用处,它可能只是说“发生了错误,哭我一条河,不,不,不”。我不看黄页。

相反,我确实喜欢自己记录异常,并且我的记录器以 开始每一行full-path-to-source-filename(line):,以便 Visual Studio 中的调试日志上的每一行都是可单击的,并且单击一行会自动打开正确的源文件,并且滚动到发出日志消息的确切行。如果你想要这种奢侈,那么就继续捕获异常,但是在记录异常之后,你必须重新抛出它,以便事情可以按照正常的过程进行。

修正案

以下是评论中添加的一些信息:

因此,您可以执行以下操作:

try
{
   ...
}
catch (Exception e)
{
    log( "information" );
    throw; //special syntax which preserves original stack trace
}
Run Code Online (Sandbox Code Playgroud)

或者

try
{
   ...
}
catch (Exception e)
{
    throw new Exception( "information", e ); //also preserves original stack trace
}
Run Code Online (Sandbox Code Playgroud)

要这样做catch( Exception e ) { log( "information" ); throw e; }因为它会丢失 的原始堆栈跟踪信息e