有没有办法在全局ASP.Net异常中显示变量值?

时间:2011-01-25 17:24:40

标签: asp.net error-handling

我在Global.asax的Application_Error方法中有一个全局错误陷阱,它将任何未处理的异常写入日志文件。

是否有报告变量名称及其值作为异常报告的一部分?

2 个答案:

答案 0 :(得分:2)

除非你使用面向方面编程做一些非常棘手的事情,否则你几乎需要确保在抛出异常时手动将任何相关信息引入堆栈跟踪。例如:

public void DoSomething(int number, string name)
{
    try
    {
        ...
    } 
    catch (Exception e)
    {
        throw new Exception("Error occurred while doing something: " +
                            new {number, name}, e);
    }
}

这样,当此异常涓涓细流到顶层时,数字和名称将包含在堆栈跟踪中。

修改

在阅读David Stratton的回答后,我觉得有必要对此进行一些扩展。我觉得即使是一些非常有经验的C#程序员也没有学到我学到的一些技巧。

首先,我想指出.NET中的异常处理系统的设计理念是InnerException专门用于此目的(在堆栈跟踪的各个点提供附加信息),做起来并不是一件好事。但是,您绝对应该将异常作为innerException构造函数参数提供,而不是将e.ToString()附加到新异常的消息中。

其次,基于我在StackOverflow上阅读的各种评论和答案,以及我自己的经验,最好:

  1. 如果没有任何具体的计划,请避免捕获异常。
  2. 当您捕获异常时,请重新抛出异常,除非您知道异常被抛出的原因并且您处于一个范围内,您知道如何优雅地退出您尝试的操作。简单地假装没有出错就是要在路上遇到更多麻烦。
  3. 重新抛出异常时,只需throw;保留原始异常的堆栈跟踪,或将原始异常包含为新异常InnerException
  4. 始终记录未重新抛出的异常。这通常只发生在UI级别,因此您可以告诉用户发生了意外情况,而不是让程序崩溃。
  5. 最后,我想提一下,匿名类型声明语法非常适合这种事情,因为它非常简洁,它会自动生成一个使用给定变量名称和值的字符串。例如,new {number, name}.ToString()可能会生成“{number = 1,name = Test}”。

答案 1 :(得分:0)

我们在某些情况下这样做,但是以迂​​回的方式。我们在粒度级别使用try / catch,如果我们想将异常传递给全局错误处理程序,我们会构建错误消息。例如:

int someCounterValue = 0; string someStringValue =“我们想要跟踪的一些字符串,以发送给全局错误处理程序。”

private void SomeFunction()
{
   try
   {
     someStringValue = "in the try block";
     someCounterValue = 1.5 // should thrown an exception

   }
   catch(Exception ex)
   {
     throw new Exception("Error in SomeFunction.  someStringValue = " + someStringValue + "; someCounterValue = " + someCounterValue.ToString() + "\r\nException details: " + ex.ToString());
   }
}

这是很多工作,所以我们真的不经常这样做。通常我们的错误处理在本地级别处理得更好,但在那些你希望将它传递给全局错误处理程序的速率情况下,这是我们找到的唯一方法,因为变量将超出范围因此,无法访问。

更简单/更少类似黑客的选项是在您的Web应用程序中设置一个名为ErrorLogger的静态类或类似的东西,只需更好地在本地处理异常并将它们传递给全局处理程序,只有当您不能在当地做。

在我看来(以及我们在这里按策略执行的方式),应该使用全局错误处理程序来捕获您忘记在更细粒度级别处理的异常。对于正确的异常处理,它不应该只是一种简单的方法。

这对我来说也是一种黑客攻击,所以如果有人有更好的选择,我也想知道它。