2010-06-04 32 views
2

我想为我的桌面应用程序构建一个错误处理程序。代码在下面列出的类ZipCM.ErrorManager中。构建一个真正的错误处理程序

我在找的是输出的文件没有给我StackTrace的正确信息。

这里是我想使用它:

Try 
    '... Some stuff here! 

    Catch ex As Exception 
      Dim objErr As New ZipCM.ErrorManager 
      objErr.Except = ex 
      objErr.Stack = New System.Diagnostics.StackTrace(True) 
      objErr.Location = "Form: SelectSite (btn_SelectSite_Click)" 
      objErr.ParseError() 
      objErr = Nothing 
     End Try 

这里是类:

Imports System.IO 

Namespace ZipCM 

    Public Class ErrorManager 

     Public Except As Exception 
     Public Location As String 
     Public Stack As System.Diagnostics.StackTrace 

     Public Sub ParseError() 
      Dim objFile As New StreamWriter(Common.BasePath & "error_" & FormatDateTime(DateTime.Today, DateFormat.ShortDate).ToString().Replace("\", "").Replace("/", "") & ".log", True) 
      With objFile 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("An Error Occured At: " & DateTime.Now) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("LOCATION:") 
       .WriteLine(Location) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("FILENAME:") 
       .WriteLine(Stack.GetFrame(0).GetFileName()) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("LINE NUMBER:") 
       .WriteLine(Stack.GetFrame(0).GetFileLineNumber()) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("SOURCE:") 
       .WriteLine(Except.Source) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("MESSAGE:") 
       .WriteLine(Except.Message) 
       .WriteLine("-------------------------------------------------") 
       .WriteLine("DATA:") 
       .WriteLine(Except.Data.ToString()) 
      End With 
      objFile.Close() 
      objFile = Nothing 
     End Sub 

    End Class 

End Namespace 

什么是happenning是.GetFileLineNumber()objErr.Stack = New System.Diagnostics.StackTrace(True)让我Try..Catch块内的行号。实际上,这是确切的行号。

对这里发生了什么的任何想法,以及我如何捕获错误发生的实际行号?

回答

3

编辑:改变了代码,以占Exception.StackTrace是一个string,而不是一个真正的StackTrace

你正在创建一个新的StackTrace,这样的话它会为你声明就行了,如果您需要原始异常的行号,请使用Exception.StackTrace中的堆栈跟踪。

我觉得你有点困惑,我看不出你为什么要创建新的StackTrace?

编辑:添加更多的比特来这里的答案,因为更容易看到的语法比在评论

目前你有行

objErr.Stack = New System.Diagnostics.StackTrace(True) 

,这意味着你正在创建一个全新的堆栈跟踪,当你创建它时开始。

而是改变该行:

objErr.Stack = New System.Diagnostics.StackTrace(ex, True) 

这将有来自在错误实际发生的堆栈跟踪。

编辑:新增完整的示例:

Private Sub a1() 
    Try 
     a2() 
    Catch ex As Exception 
     Dim st As New StackTrace(True) 
     Debug.WriteLine(String.Format("ST after exception, will give line number for where st was created. Line No: {0}", st.GetFrame(0).GetFileLineNumber())) 

     st = New StackTrace(ex, True) 
     Debug.WriteLine(String.Format("ST after exception using exception info, will give line number for where exception was created. Line No: {0}", st.GetFrame(0).GetFileLineNumber())) 
    End Try 
End Sub 

Private Sub a2() 
    Dim st As New StackTrace(True) 
    Debug.WriteLine(String.Format("ST before exception, will give line number for where st was created. Line No: {0}", st.GetFrame(0).GetFileLineNumber())) 
    Dim b As Integer = 0 
    Dim a As Integer = 1/b 
End Sub 
+0

我很困惑。我的代码应该放在哪里? – 2010-06-23 18:50:16

+0

@Kevin:请参阅我的更新答案,在前面加上'Edit:'作为更好的解释。 – 2010-06-23 19:23:17

+0

对不起,但这只会带来错误。关于.StackTrace是一个字符串,而GetFrame不是它的方法或属性... – 2010-06-26 12:46:05

0

你并不需要包括堆栈属性为你的错误管理,因为你有过异常访问堆栈跟踪。

从以往的经验,我会创造在ErrorManager一个Shared Sub Write(ex As Exception, location As String)方法,并在你的Catch语句调用为:

ZipCM.ErrorManager.Write(ex, "Form: SelectSite (btn_SelectSite_Click)")

这种变化会导致更干净的代码,减少了需要编写大量的代码每个Catch语句,并允许您更改Write的实现,而无需重新访问/返工/重构每个Catch语句。

例如,您可以将Write方法更改为也调用Debug.WriteLine(ex),以便您可以查看在调试过程中处理哪些异常,而无需打开该文件。此外,您可能需要包含WriteNotify方法,该方法显示异常的消息框,然后调用Write方法来记录异常。

1

解决:用这个新

.WriteLine(Stack.GetFrame(0).GetFileLineNumber()) 

:代码

.WriteLine(Stack.GetFrame(Stack.FrameCount - 1).GetFileLineNumber) 

,你会看到,它会返回准确LINE_NUMBER你应该改变了错误的指令,原码 发生运行时错误!