如何正确提出阶级错误

时间:2018-06-06 03:31:56

标签: class error-handling scope vb6

我的问题是:如何在类中正确引发错误,以便实例化该类的调用者可以使用正确的错误处理技术?

我正在升级不使用类的旧VB6意大利面条代码。在过去,我总是使用 On Error Resume Next On Error Goto myLabel 来处理错误替代品对我的代码来说不是更清洁。

但是,我无法让调用者处理错误,因为如果我在类的方法或属性中引发错误,则无论是否使用 On Error ,错误都会引发语句从调用者处捕获它。示例代码将是这样的:

MyClass的:

Public Sub Bar()
    If valid Then
        'some code here
    Else
        Err.Raise 5
    End if
End Sub

的MainForm:

Private Sub CallFoo()
    Dim foo as New MyClass

    On Error Goto fooliure 'Starts ignoring errors
    Call foo.Bar() 'Program stops with an exception
    On Error Goto 0 'Ends error handling

    Exit Sub
    fooliure:
        'Error handling code
End Sub

此外,微软表示,这就是他们打算如上所述here在VB 6.0中执行错误处理的方式。

此时我正在考虑在我的班级中使用一个会收集调用者可以检索到的错误的对象。如果我能避免这样做,我会,但到目前为止我找不到答案。

1 个答案:

答案 0 :(得分:0)

David,这是一个关于VBA错误处理101的简短教程。

  • Err对象。这是一个保存当前错误的单例对象。不要尝试实例化此对象(即不要使用Set objErr = New Err - 这将失败)
  • On Error - 设置错误处理。可能的错误处理程序:
    • On Error GoTo Label - 遇到错误时执行跳转到Label
    • On Error Resume Next - 遇到错误时执行跳转到下一行
    • On Error GoTo 0 - 关闭当前错误处理程序。任何后续错误都将由调用者处理
    • On Error Resume - 执行跳转到导致错误的行(不推荐)
  • 在以下情况下清除Err对象(丢失当前错误):
    • 子程序,函数或属性称为
    • 子程序,功能或属性通常退出
    • 执行On Error语句
    • Err.Clear在调用
    • 时清除当前错误
  • 提出例外情况。您可以随时提出错误。规范形式:

    Err.Raise 1001 + vbObjectError, Description:="An exception occurred."
    
  • 自定义错误:使用vbObjectError发出用户定义的错误。例:
    • 1001 + vbObjectError
    • 整数范围是0到65535
  • 错误处理顺序:
    1. 如果例程中定义了本地错误处理程序,则执行它
    2. 如果没有本地处理程序,则将错误提交给调用者
    3. 如果调用者没有处理程序,则一直提出错误,直到找到本地处理程序
    4. 如果没有顶级处理程序,则应用程序终止
  • 创建错误链。创建显示原始错误的错误链非常有用,并在发生错误时显示堆栈上的例程列表。去做这个:
    • 每个可能导致错误的例程添加错误处理
    • 始终将错误重新提升给来电者
    • 在重新引发错误时为Err.Source添加一个字符串命名例程
    • 顶级调用例程可以使用MsgBox通知用户错误(或其他日志记录可以实现)

以下是演示这些想法的代码示例:

Public Sub TestErrorLevel1()

    On Error GoTo HandleErr ' clears Err object

    TestErrorLevel2

    Exit Sub

HandleErr:
    ' top-level error handler -- nothing else to raise error to
    ' show error and complete call chain
    MsgBox "Error: " & Err.Number & vbCrLf & Err.Description & vbCrLf _
        & "Source: modTest.TestErrorLevel1" & vbCrLf & Err.Source
End Sub

Public Sub TestErrorLevel2()

    On Error GoTo HandleErr ' clears Err object

    TestErrorLevel3

    Exit Sub

HandleErr:
    ' re-raise error, adding this subroutine to call chain
    Err.Raise Err.Number, "modTest.TestErrorLevel2" & vbCrLf & Err.Source, Err.Description
End Sub

Public Sub TestErrorLevel3()

    On Error GoTo HandleErr ' clears Err object

    Err.Raise 1001 + vbObjectError, Description:="User-defined error. Offset range from 0 to 65535"

    Exit Sub

HandleErr:
    ' re-raise: add module and routine to originating error
    Err.Raise Err.Number, "modTest.TestErrorLevel3" & vbCrLf & Err.Source, Err.Description
End Sub