2009-11-09 198 views
1

到现在为止,我记录了错误消息和异常的堆栈跟踪。但是,如果我不记录try块中使用的所有变量,我认为这样做不是很有用。如果我可以看到try块中使用的所有变量,我想我会更好地了解导致异常的原因,并且可以避免它再次发生。当发生异常时记录什么

你们是怎么登录的?

谢谢

回答

4

主要我们记录错误消息和堆栈跟踪。我们还会在日志中添加注释以说明发生这种情况的可能原因。这些消息通常就像“如果它在这里失败,用户会话未设置,并且可能由于会话重置而发生。”通常这些信息是让我们朝着正确方向寻找的东西。

如果您的try catch块太大而无法做到这一点,我会考虑将其分离出来,以便更小块。如果你不想这样做,那么我会开始为不同类型的异常设置不同的catch块。

catch(FileNotFoundException ex) 
{} 
catch(Exception regularException) 
{} 

这样你就可以定制任何额外的信息,该类型的异常,并有一种普遍的例外作为最后一个catch块,以确保东西并不意外逃脱。

+0

这是一个好主意。我会记录一条自定义错误消息。但是,如果我的try块太大,有很多事情可能会出错,并且我只有一个捕获“System.Exception”的catch块。如何区分自定义错误消息,因为如果错误消息显示“对象未设置为实例...”,我们无法知道其中有多少个对象为空...... 谢谢 – iJK 2009-11-09 14:48:39

+0

酷感谢:-) – iJK 2009-11-09 15:11:16

+0

@ iHeartDucks:如果您有代码可能出现多个错误,请将多个try/catch块放置在可能会出错的行的周围。然后你可以定制你想要的信息。 – 2009-11-09 15:12:09

0

一般而言,我只记录异常消息和堆栈跟踪,并尝试记录足够的调试信息,以便我可以确定上下文中发生了什么。通常这是绰绰有余的细节来弄清楚出了什么问题。

在我无法弄清楚异常情况如何发生的情况下,我添加了适用变量值的附加调试日志记录。当然,这仅适用于应用程序,并且可以在需要时临时换出程序集。如果没有这种类型的可访问性,那么你可能想看看Gibraltar。它提供了丰富的调试信息,可以从远程客户端发送并具有各种精美的表单来查看它。

1

我总是会试图记录方法中的所有内容,主要是因为将来维护代码的巨大维护开销。

此外,您可能必须确保您的日志记录代码具有上下文感知能力,即如果您使用嵌套在对象中的属性,则日志记录代码将需要了解如何在日志期间获取这些变量,以及这你必须确保记录器可能做出的任何请求不会影响任何事情的状态,或者它不会代表实际状态。

为什么不努力在方法开始时验证参数,然后在需要的地方对代码进行空检查?

+0

我会验证所有输入(在客户端和服务器上)。是的,我同意在记录对象的属性时必须小心。我想,这只是我想知道发生的那些情况以及为什么在采取n个预防措施后出现错误。 – iJK 2009-11-09 14:54:04

5

正如其他人所说,在记录异常时,我通常会记录exception.ToString(),它通常只包含消息,堆栈跟踪和内部异常。

但是在System.Exception上定义的属性经常被遗忘,但可能是您正在寻找的属性。它属于IDictionary Data属性。在该字典中,您可以放置​​任何您想要的东西,然后在记录异常时使用它。

这里是一个越野车的功能,使用它另外一个,并且无论是否存在uncatched异常栈展开时调用方法的简单的例子:

public static int BuggyFoo(int notZeroPlease) 
{ 
    return 5/notZeroPlease; 
} 

public static int UseBuggyFoo(int userInput) 
{ 
    var myValue = userInput >> 2; 
    try 
    { 
     var foo = BuggyFoo(myValue); 
     return (foo + 5); 
    } 
    catch (Exception e) 
    { 
     e.Data["userInput"] = userInput; 
     e.Data["myValue"] = myValue; 
     throw; 
    } 
} 

public static void Application_OnError(Exception e) 
{ 
    var sb = new StringBuilder(); 
    foreach (var k in e.Data.Keys) 
    { 
     sb.AppendFormat("Data[{0}] = {1}\n", k, e.Data[k]) 
    } 
    Utilities.Logger.Log(sb.ToString(), e); 
} 

但这应该适量使用..否则(如果你的代码是越野车)你会有巨大的日志文件!

祝你好运!

编辑: 如果你不知道这一点Application_OnError()方法,这里是一个可能的例证:

public static void Application_OnError(Exception e) 
{ /* ... */ } 

public static void Main() 
{ 
    try 
    { 
     /* ... */ 
    } 
    catch (Exception e) 
    { 
     Application_OnError(e); 
    } 
} 

如果要创建一个Web应用程序,使用ASP.NET,让我们说,那么你应该已经有一个Application_OnError方法在这种情况下被调用。

+0

是的,我也使用字典对象。我认为结合你的答案+凯文的答案是一条路。 – iJK 2009-11-09 15:18:29

0

偶尔,我会记录内部异常以及主要异常消息。这可以提供更具体的异常信息并允许更轻松的调试。

0

我有一个对象,我称之为'UserAction',每当用户以某种方式与UI进行交互时,在列表中推入另一个用户活动,例如“clicked x”或“将p从x拖动到y”。它还具有诸如日期/时间,用户名等信息。当发生异常时,软件会自动发送电子邮件通知异常消息,堆栈跟踪和UserAction日志的转储。试图重现问题可能会非常有帮助。

我通常在用户有机会到我的办公室之前知道问题是什么。

相关问题