我经常在VB6应用程序中遇到这种情况
Private Sub DoSomething
On Error Goto err1
Call ProcessLargeBatch1
Call ProcessLargeBatch2
'... more ...'
Exit Sub
err1:
Call Cleanup 'Specific for DoSomething'
Call HandleError 'General error handling: Logging, message box, ...'
End Sub
清理过程有时会还原操作,回滚事务,删除临时文件等。在大多数情况下,此操作也可能失败。
在这种情况下我该怎么办?我将On Error Resume Next
添加到错误处理程序中,但会删除现有的Err
对象。向Cleanup
添加错误处理程序也存在同样的问题。
确保原始错误仍然得到处理/记录的最佳方法是什么?
编辑:另外一个问题是我还想通知用户错误。有时重要的是,清理很快发生,我不希望消息框长时间阻止应用程序,并在用户确认错误后进行清理。
答案 0 :(得分:4)
首先,从Err对象中读取您需要的所有信息,即数字,描述等,然后清除错误并执行您想要的操作。
更改通知用户使用已缓存的值的方式,而不是使用Err对象本身。
答案 1 :(得分:3)
从您的示例中,您正在正确地进行清理。你的HandleError应该只记录错误而不做任何UI。用户界面在表单级别进行处理。
发生错误时需要的是
这将调用堆栈到调用原始代码的事件。然后序列将成为
请注意,您的错误记录可以是智能的,因为相同错误的后续日志只能添加到记录的调用堆栈中。
您希望确保每个事件都有错误处理程序。并非每个程序都需要一个但绝对是每个事件。事件中未处理的错误将导致VB6应用程序意外关闭。
答案 2 :(得分:2)
如果我可以在一个地方处理所有错误,我通常会进入这样的结构:
Public Sub SubThatShouldHandleErrors()
Const ROUTINE_NAME = "SubThatShouldHandleErrors"
On Error Goto Catch
' "normal" processing here...
Finally:
' non-error case falls through to here
' perform clean-up that must happen even when an error occurred
On Error Goto 0 ' reset: not really needed any more, but it makes me feel more comfortable
Exit Sub
Catch:
' Error handling here, I may have logging that uses ROUTINE_NAME
Resume Finally
End Sub
如果我需要多个错误处理程序,我会非常努力地重构我的代码以使其不是这种情况但如果绝对必要,我会编写一个自定义处理程序;我的模板只是一个指南。
答案 3 :(得分:1)
首先记录您的错误。然后执行On Error Resume Next。将清理封装在具有自己的错误处理方法中。这应该是你最好的选择。
答案 4 :(得分:0)
我真的不喜欢错误处理程序。这就是我的工作;
' lots of code that will probably work
On Error Resume Next
Open "c:\filethatdoesntexist.txt" For Input As #1
Error.CopyError
On Error Goto 0
Select Case Error.Number
Case 53'File doesn't exist
' handle that error here
Case 0
' no error
Case Else
' Just throw the error on
Err.Raise Error.Number, Error.Description, ...
End Select
' more code that will probably work