在VB6中处理错误的更好方法是什么

时间:2020-03-06 14:33:09  来源:igfitidea点击:

我有VB6应用程序,我想在其中添加一些良好的错误处理功能,该功能可以告诉我错误发生的时间和确切的位置,有人可以建议这样做的好方法

解决方案

首先,获得用于Visual Basic 6的MZTools,它是免费且无价的。其次,在每个函数上添加一个自定义错误处理程序(是的,每个函数)。我们使用的错误处理程序如下所示:

On Error GoTo {PROCEDURE_NAME}_Error

{PROCEDURE_BODY}

    On Error GoTo 0
    Exit {PROCEDURE_TYPE}

{PROCEDURE_NAME}_Error:

   LogError "Error " & Err.Number & " (" & Err.Description & ") in line " & Erl & _
            ", in procedure {PROCEDURE_NAME} of {MODULE_TYPE} {MODULE_NAME}"

然后创建一个LogError函数,将错误记录到光盘上。接下来,在发布代码之前,将行号添加到每个函数中(这也是MZTools内置的)。从现在开始,我们将从错误日志中了解发生的一切。如果可能的话,还上传错误日志并从现场实际检查它们。

这是我们在VB6中处理意外的全局错误(其众多缺陷之一)时所能做的最好的事情,实际上,这仅应用于查找意外的错误。如果我们知道在特定情况下有可能发生错误,则应捕获该特定错误并进行处理。如果我们知道某个部分中发生的错误将导致不稳定(文件IO,内存问题等),请警告用户并知道我们处于"未知状态",并且可能会发生"坏事"。显然使用友好的术语来使用户了解情况,但并不感到害怕。

使用On Error语句和Err对象。

ON ERROR GOTO

Err

目的。

这里有一个教程。

是的,请听Kris的建议并获得MZTools。

我们可以在复杂过程的区域外添加行号,ERL将在错误处理程序中报告该行,以跟踪引起错误的区域。

10
    ...group of statements
20
    ...group of statements
30
    ...and so on

没有添加模块的简单方法,对类模块很有用:

抢占每个功能/子:

On Error Goto Handler

处理程序/气泡:

Handler:
  Err.Raise Err.Number, "(function_name)->" & Err.source, Err.Description

瞧,贫民窟堆栈跟踪。

我使用自家的Error.bas模块来减少报告和重新筹集的麻烦。

这是其内容(按长度编辑):

Option Explicit

Public Sub ReportFrom(Source As Variant, Optional Procedure As String)
    If Err.Number Then
        'Backup Error Contents'
        Dim ErrNumber As Long: ErrNumber = Err.Number
        Dim ErrSource As String: ErrSource = Err.Source
        Dim ErrDescription As String: ErrDescription = Err.Description
        Dim ErrHelpFile As String: ErrHelpFile = Err.HelpFile
        Dim ErrHelpContext As Long: ErrHelpContext = Err.HelpContext
        Dim ErrLastDllError As Long: ErrLastDllError = Err.LastDllError
    On Error Resume Next
        'Retrieve Source Name'
        Dim SourceName As String
        If VarType(Source) = vbObject Then
            SourceName = TypeName(Source)
        Else
            SourceName = CStr(Source)
        End If
        If LenB(Procedure) Then
            SourceName = SourceName & "." & Procedure
        End If
        Err.Clear
        'Do your normal error reporting including logging, etc'
        MsgBox "Error " & CStr(ErrNumber) & vbLf & "Source: " & ErrSource & vbCrLf & "Procedure: " & SourceName & vbLf & "Description: " & ErrDescription & vbLf & "Last DLL Error: " & Hex$(ErrLastDllError)
        'Report failure in logging'
        If Err.Number Then
            MsgBox "Additionally, the error failed to be logged properly"
            Err.Clear
        End If
    End If
End Sub

Public Sub Reraise(Optional ByVal NewSource As String)
    If LenB(NewSource) Then
        NewSource = NewSource & " -> " & Err.Source
    Else
        NewSource = Err.Source
    End If
    Err.Raise Err.Number, NewSource, Err.Description, Err.HelpFile, Err.HelpContext
End Sub

报告错误很简单:

Public Sub Form_Load()
On Error Goto HError
    MsgBox 1/0
    Exit Sub
HError:
    Error.ReportFrom Me, "Form_Load"
End Sub

重新产生错误就像使用新来源调用Error.Reraise一样简单。

如果使用符号调试信息进行编译,虽然可以从调用堆栈中检索"源"和"过程"参数,但其可靠性不足以用于生产应用程序