15

我有 VB6 应用程序,我想在其中添加一些好的错误处理函数,它可以告诉我错误是什么以及它发生的确切位置,任何人都可以建议这样做的好方法

4

7 回答 7

30

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

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、内存问题等),请警告用户并知道您处于“未知状态”并且可能会发生“坏事”。显然使用友好的术语来让用户了解情况,但不要害怕。

于 2008-09-22T17:40:32.377 回答
13

一种无需额外模块的简单方法,对类模块很有用:

抢占每个功能/子:

On Error Goto Handler

处理程序/冒泡:

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

瞧,贫民窟堆栈跟踪。

于 2008-09-22T18:11:18.857 回答
4

我使用了一个自制的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重新提出错误就像使用新源调用一样简单。

如果使用符号调试信息进行编译,虽然可以从调用堆栈中检索SourceProcedure参数,但在生产应用程序中使用它还不够可靠

于 2008-09-24T17:43:43.320 回答
3

错误转到

Err

目的。

这里有一个教程。

于 2008-09-22T17:42:10.110 回答
1

是的,听从 Kris 的建议并获取 MZTools。

您可以将行号添加到复杂过程的部分区域,ERL 将在错误处理程序中报告这些区域,以追踪导致错误的区域。

10
    ...group of statements
20
    ...group of statements
30
    ...and so on
于 2008-09-22T17:51:22.803 回答
1

使用在

dim errhndl as string
on error goto errhndl
errhndl:
msgbox "Error"
于 2016-08-23T21:41:08.490 回答
0

使用 On Error 语句和 Err 对象。

于 2008-09-22T17:40:59.333 回答