我有VB6应用程序,我想在其中放置一些好的错误处理功能,它可以告诉我错误是什么,确切地点发生时,有人可以建议这样做的好方法
答案 0 :(得分:29)
首先,去获取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,内存问题等)警告用户并且知道您处于“未知状态”并且“坏事”可能会发生。显然,使用友好的术语来保持用户的信息,但不要害怕。
答案 1 :(得分:12)
没有附加模块的简单方法,对类模块很有用:
先占每个函数/ subs:
On Error Goto Handler
处理程序/ bubbleup:
Handler:
Err.Raise Err.Number, "(function_name)->" & Err.source, Err.Description
瞧,贫民窟堆积痕迹。
答案 2 :(得分: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
一样简单。
虽然如果使用符号调试信息进行编译,可以从调用堆栈中检索Source
和Procedure
参数,但在生产应用程序中使用它的可靠性不够
答案 3 :(得分:2)
答案 4 :(得分:1)
是的,请听Kris的建议并获得MZTools。
您可以在复杂程序的区域中添加行号,ERL将在错误处理程序中报告这些区域,以跟踪导致错误的区域。
10
...group of statements
20
...group of statements
30
...and so on
答案 5 :(得分:1)
使用
dim errhndl as string
on error goto errhndl
errhndl:
msgbox "Error"
答案 6 :(得分:0)
使用On Error语句和Err对象。