How to re-enable the default error handling in VB6

2019-04-23 13:03发布

I have some code with various "On Error Goto" error handlers in a few places to handle some broken third party hardware. I was getting an overflow error (read from the Err variable) in a routine that doesn't have an error trap but is called by a routine that does. I always thought error traps were only valid in the routine they were declared, but it looks like an error in a subroutine can cause it to go to the calling function's error trap.

So I turned off the calling function's error trap and found my overflow and all is well. But before I did that, I spent some time trying to find a programatic way to get VB to return to its default error handling inside that routine (so I wouldn't have to modify outside code to debug), but I couldn't. The only error commands I could find:

  On Error GoTo [label]
  On Error Resume Next
  On Error Goto 0
  On Error GoTo -1

all turn on the manual error handling - is there a way to turn it off (back to the VB6 default)?

8条回答
太酷不给撩
2楼-- · 2019-04-23 13:25

There is no "On Error GoTo -1" so I have no idea where you got that.

VB6 exception handling is covered very thoroughly in the manual.

查看更多
对你真心纯属浪费
3楼-- · 2019-04-23 13:31

This is explained thoroughly in the VB6 manual under Error Handling Hierarchy. On Error Goto 0 disables the error handler in the current procedure, not in the procedures that called it.

If an error occurs in a procedure and this procedure doesn't have an enabled error handler, Visual Basic searches backward through the pending procedures in the calls list — and executes the first enabled error handler it finds. If it doesn't encounter an enabled error handler anywhere in the calls list, it presents a default unexpected error message and halts execution.

As others have said, you can go to Tools-Options-General tab and choose Break on all errors. That effectively disables all your On Error statements - the IDE will break immediately on every error.

That can be irritating if your VB6 code throws errors as part of normal operation. For instance when you check whether a file exists, or when the user presses cancel in a common dialogue. You don't want the IDE to break every time on those lines. But you might have boilerplate error handlers in all your event handling procedures, to stop the program crashing out on unexpected errors. But they are a nuisance when you're debugging problems because the IDE doesn't break on the line with the error. One trick is to switch off those error handlers when running in the IDE, but keep them in the built executable. You do it like this.

Drop these functions into a module.

Public Function InIDE() As Boolean 
  Debug.Assert Not TestIDE(InIDE) 
End Function 

Private Function TestIDE(Test As Boolean) As Boolean 
  Test = True 
End Function 

Then you can write your error handlers like this.

Private Sub Form_Load() 
  If Not InIDE() Then On Error Goto PreventCrashes 
  <lots of code> 
  Exit Sub 

PreventCrashes: 
  <report the error> 
End Sub 

Pinched from here. Another tip - use the free add-in MZTools to automatically add these boilerplate error handlers. For production-quality code, you could go further and put an error handler in every routine to create a ghetto stack trace. You might also log the errors immediately in every error handler.

EDIT: Ant has correctly pointed out that On Error Goto -1 is a VB.Net statement and isn't valid in VB6.

EDIT: Arvo and OneNerd have written answers with some interesting discussion of emulating Finally teardown blocks in VB6 error handling. The discussion in this question is also worth a look.

查看更多
看我几分像从前
4楼-- · 2019-04-23 13:42

There is a handy right-click menu that lets you turn error handling on and off. Just right-click on a code window and select Toggle, then you can choose "Break on all errors". This will have the effect of disabling all your "On Error" statements.

查看更多
走好不送
5楼-- · 2019-04-23 13:45
on error goto 0

Should be what you want... It should cause the error to the thrown, and in turn probably unwind up to the RTL...

It's been a long time, but I'm pretty sure that's what you want.

on error resume next

will just continue to the next statement, so you NEED to have plenty of

if err.Number <> 0 then

statements in your code where errors CAN occur...

查看更多
Animai°情兽
6楼-- · 2019-04-23 13:48

There's clear and simple way to reset error status - use keyword Resume. There are three possibilities:

Resume
Resume Next
Resume <Label>

Resume continues execution at errored line, Resume Next at next line and least talked Resume Label continues at label. Very useful to create try-catch-finally like constructs in VB6. Borrowed and modified from OneNerd answer:

Function MyFunction() as String

'-- start of error block
'
 On Error Goto Catch
   ' do something here that might cause an error
   MyFunction = "IT WORKED"
   Goto Finally

   Catch:
   ' error occured - do something else
   MyFunction = Err.Description
   Err.Clear
   Resume Finally          ''added to clear error status

 Finally:
   On Error Resume Next    ''added to avoid repeated errors
   ' put your finally code here

 '
 '-- end of error block

End Function

Simple Err.Clear doesn't help, if some subsequential error occurs in Finally block; Resume Finally does reset internal error state though.

查看更多
We Are One
7楼-- · 2019-04-23 13:48

Have to agree with LarryF, On Error Goto 0 should turn off explicit error-handling that has been turned on by On Error Resume Next. Functions and subroutines do have their own scope for this though. From Dr. Scripto at Microsoft:

Putting On Error Resume Next at the beginning of the script, as we often do, makes it apply to the entire body of the script. But, as we'll see in later examples, its scope does not include functions or subroutines. If you want to handle errors within a function or subroutine, you must also include On Error Resume Next in each of them before checking the Err object.

You can turn error-handling off with On Error GoTo 0. So it's possible to turn error-handling on with On Error Resume Next just before you want to check the Err object, and turn it off after with On Error GoTo 0.

查看更多
登录 后发表回答