【问题标题】:Building A True Error Handler构建真正的错误处理程序
【发布时间】:2010-06-04 20:27:38
【问题描述】:

我正在尝试为我的桌面应用程序构建一个错误处理程序。代码在下面列出的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

正在发生的事情是.GetFileLineNumber() 正在从我的Try..Catch 块中的objErr.Stack = New System.Diagnostics.StackTrace(True) 获取行号。事实上,它是打开的确切行号。

对这里发生的事情有什么想法,以及如何捕捉错误发生的实际行号?

【问题讨论】:

    标签: vb.net desktop-application


    【解决方案1】:

    编辑:更改代码以说明 Exception.StackTracestring 而不是真正的 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
    

    【讨论】:

    • @Kevin:请在以Edit: 为前缀的行下查看我的更新答案以获得更好的解释。
    • 对不起,但这只会带来错误。 .StackTrace 是一个字符串,而 GetFrame 不是它的方法或属性...
    • @Kevin:对不起,我的错误,我忘了它是Exception中的一个字符串,你必须创建一个新的StackTrace,但你必须将Exception作为参数发送,所以应该是objErr.Stack = New System.Diagnostics.StackTrace(ex, True)。我已经更新了上面的答案,可能更容易阅读。
    • 好吧....我们到了某个地方,没有更多的字符串问题,但是没有行号,没有文件等?
    • @Kevin:我添加了一个完整的代码示例。我只是创建了一个新的 WinForms 项目,为表单的 Load 事件创建一个事件处理程序,并从该处理程序调用 a1 方法,这一切都按预期工作。
    【解决方案2】:

    已解决:您应该更改原始代码的错误指令:

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

    有了这个新的:

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

    您会看到,它将返回确切的 Line_Number 代码 发生运行时错误的地方!!

    【讨论】:

      【解决方案3】:

      您不需要为 ErrorManager 包含 Stack 属性,因为您可以通过异常访问堆栈跟踪。

      根据经验,我会在 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 方法来记录异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-18
        • 1970-01-01
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多