【问题标题】:Getting a more useful/accurate error message获得更有用/更准确的错误消息
【发布时间】:2018-10-17 16:55:16
【问题描述】:

我们遇到了一个 Access 前端的问题,它看似随机但不断地让用户超时而没有任何解释。这是一个长期存在的问题,每次发生断开连接时,我们都会收到导致问题的子程序和一般错误消息。

我开始认为该错误消息具有误导性,它给出了一个错误代码为 0 的通用“连接失败”。在谷歌上搜索显然意味着没有发生错误的代码后?

我用的是C#而不是VBA,所以不太熟悉,但是错误处理如下:

    Private Sub Form_Timer()

    Dim blnSystemMaintenance As Boolean

    On Error GoTo ErrHand

    ' Check for System Maintenance.
    blnSystemMaintenance = DLookup("SystemMaintenance", "ConfigItems")
    If blnSystemMaintenance Then

    //Do stuff
        Else
    //Do stuff
        End If

    //Do stuff

    End If

    ErrExit:
        Exit Sub
        Resume
    ErrHand:
    '    If Err.Number = 1 Then

    '    Else
            MsgBox "Error number: " & Err.Number & vbCrLf & _
           "Error description: " & Err.Description, vbCritical, _
           "Unexpected Error Occurred in Sub: Form_Timer"
    Resume ErrExit
    '    End If


    End Sub

有没有办法获得更有用的错误消息?

【问题讨论】:

  • 你可以在里面放行号,但是很复杂。
  • 行号是什么意思?就像返回错误行一样?我希望更多的是某种适当的异常消息,而不仅仅是“连接失败”
  • 如果您的代码调用其他程序,所有这些程序也应该有错误处理程序,否则,来自这些程序的错误将被“冒泡”,直到到达带有错误处理程序的代码并且错误代码/消息将是完全误导。
  • 它打开另一个表单,但是它打开的表单中的每个子都有自己的错误消息,通知用户哪个子失败,所以我认为那里应该没问题

标签: ms-access vba


【解决方案1】:

域聚合通常不提供描述性错误消息。我假设您的数据库在运行域聚合时遇到连接到后端的问题。

您可以轻松地用记录集调用替换您的域聚合:

blnSystemMaintenance = CurrentDb.OpenRecordset("SELECT SystemMaintenance FROM ConfigItems")(0).Value

通常,如果在使用记录集时发生错误,这些错误会提供更多描述性错误。

【讨论】:

  • 感谢您的回答,令人沮丧的是,我不能自己更改它并直接对其进行测试,所以我必须提出请求,看看这是否有帮助。
【解决方案2】:

有时错误消息可能会误导某些类型的函数,例如DLookup,这是一个系统问题,但有时错误消息会产生误导,因为并非所有程序都有正确的错误处理程序,而且很难定位问题,特别是如果开发人员无法直接访问应用程序。因此,正确的错误处理程序可以显着简化故障排除。

通常我使用两种类型的错误处理程序,它们可以提供非常清晰的诊断信息。最常见 - 过程的常见错误处理程序,可能与用户交互并通常由系统调用 - 事件处理程序:

Private Sub Frame2_Click()
    On Error GoTo ErrorHandler
    'code here
ExitHere:
    On Error Resume Next
    Exit Sub
    Resume '>> remove in release
ErrorHandler:
    MsgBox "Error " & err.Number & " (" & err.Description & "), Line " & Erl & " in procedure Frame2_Click of Form_Form1", vbExclamation + vbMsgBoxHelpButton, "Error " & Now()
    Resume ExitHere
End Sub

第二种类型的处理程序 - 对于只能由其他 VBA 程序调用的程序,“气泡”处理程序,它将有关错误的信息添加到错误描述中并将错误传递给调用程序:

Sub MySub()
    On Error GoTo ErrorHandler
    'code here
ExitHere:
    Exit Sub
    Resume '>> remove in release
ErrorHandler:
    Debug.Assert Not (STOP_AT_ERROR And IS_DEV) '>> remove in release
    err.Raise err.Number, "MySub of Form_Form1", err.Description & vbCrLf & "in MySub of Form_Form1 at " & Erl
End Sub

它允许显示带有错误行和过程名称的完整调用堆栈。行号应该添加到每一行代码。

为了简化调试,我使用了两个常量:如果 STOP_AT_ERRORTrueIS_DEVTrue,代码执行会在错误发生后立即停止而不会冒泡,并允许检查变量。为了检查,我使用 Ctrl-F9 将代码执行指针移动到 Resume 行,然后按 F8 并且代码指针移动到导致错误的行。

在生产或 QA 版本中,只需将 IS_DEV 更改为 False,代码不会停在 Debug.Assert 行。

为了自动生成错误处理程序和添加行号,我使用第三方软件,例如 MZ-Tools。可以手动完成,但是比较费时间

【讨论】:

  • 这个问题的一般观点很好(很好的错误处理代码!),但它不适用于这种情况,因为它是一种罕见的错误类型,不能由 err 生成。提高:err.Number 为零,而 err.Description 已设置!这是一个永远不应该发生的场景(如果发生了,您的第二个错误处理程序将因 RTE 5 Invalid procedure call or argument 而失败)。我想我以前在与后端的连接问题时遇到过这种情况,但请注意这种特殊类型的错误会使您的错误处理程序失败。
猜你喜欢
  • 1970-01-01
  • 2012-10-18
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多