Home
Foreword
Preface
Class Idioms
Collections
Implements
Constructors
Terminate
Forms
On Error
Frameworks
F.A.Q.
Value-added
FSMs
Constants
GOTO
Hungarian
Nothing
Properties
Big EXEs

Error handling is one of the most asked-about areas of Visual Basic programming, so here Iīve addressed some of the more common questions I have seen asked.

Q. I put an On Error GoTo in my Sub Main, but it doesn't seem to catch any errors. Why?

A. An On Error in Sub Main will only catch errors that happen in Sub Main or in function calls that can be traced back to Sub Main. Most function calls in a VB program can be traced back to an event handler (a button click, for example), not to Sub Main. Sub Main is not the same as the 'main program' in traditional programming languages - it's simply a function that's guaranteed to run first.

Q. How can I ensure that my VB program never halts when an error occurs?

A. You must put an On Error Goto or On Error Resume Next in every event handler in your program (Initialize events donīt count). If you have a Sub Main you must put an On Error in there too. Fundamentally, anything that can appear on the Call Stack dialog above a [<Non-Basic Code>] line must have an error handler. In some circumstances this can include call-back methods as well as event handlers.

Q. Can I define my error handling in a single function that's called by my On Error statement?

A. Yes, although your function must be sufficiently general to handle any error. It's usual to use a standard function to report errors but to code the specific recovery action separately for each On Error block.

Q. I have an On Error statement in one of my functions but the error reported seems to have nothing to do with the code in that function. What's going on?

A . Your function calls another function that doesn't contain an on Error Statement. When an error occurs VB looks for the most recently-executed On Error statement and does the recovery actions associated with it. If it can't find an On Error statement in the current function, the function is abandoned and VB looks for an On Error statement in the calling function. If it finds one, the error is reported at the line that invoked the offending function. This process continues until VB either finds an On Error statement or reaches the top of the calling hierarchy (always an event handler or Sub Main).

Q. I've got On Error GoTo statements in all my functions and events but my program still halts on certain errors. Why?

A. You are doing something in an event handler that causes another error. Error handling in a function is disabled when an error occurs. You must execute a Resume to switch it back on.

Q. I keep getting an error report but when I check Err, its value is 0. What's happening?

A. You need an Exit Sub before your error block. Your function is dropping into the error block even though an error hasn't been raised.

Q . The first statement in my error handler is On Error Resume Next, but my program still terminates if another error occurs. Why?

A. As soon as an error occurs, error handling in your function is disabled and the only way you can re-enable it is by executing a Resume statement. You can do this by having a label on the second line of your error handling block and using Resume <label>. Executing an On Error Resume Next will now ignore subsequent errors.

Q. Why do I need to do a Resume instead of just exiting my function after reporting an error?

A. You don't - you can use Exit Sub instead.

Q. Why is the code in my error handler sometimes executed twice?

A. You are probably using a Goto to jump to your error block, and then trying to execute a Resume statement (the error you are seeing is `Resume without Gotoī). Use Err.Raise to raise an error.

Q. Can I call a function from an error handler block to report the error? / Can I call a cleanup function before reporting an error?

A. Yes, but if that function contains any error handling statements you will lose the contents of the Err object. The easiest way to avoid losing the error information is to pass the contents of Err as ByVal parameters to your reporting function.

Q. I have On Error Resume Next in all my functions. My program is very stable but it doesn't seem to work properly. Why?

A. Because lots of runtime errors are happening but you never get to know about them. On Error resume Next is very dangerous because the only way you can detect errors is to have your code check Err.Number manually.

Q. When should I use On Error Resume Next?

A. If you want to handle errors generated by a specific line of code without coding an error block, use On Error Resume Next and then check the value of Err.Number when your line has executed. This is cumbersome in practice, particularly if you only use it for particular lines, since you need to follow it with an On Error Goto statement to re-enable the default error handling.

Q. My program has comprehensive error handling and works fine as an EXE, but it often falls over when running in design mode. / Some of my error handlers work as expected but VB seems to ignore others. / I have error handlers in each of my form's event handlers, but VB just halts instead of passing control to them when an error occurs.

A. The error handlers that donīt seem to work are in form or class modules and you have your error trapping mode set to `break in class moduleī (the default). Change this to `break on unhandled errorsī in the Tools/Options dialog or in the context menu (right mouse button) of any code window.

Q. Do I need to code On Error Goto 0 at the end of my error handlers?

A. No.

Q. What use is On Error Goto 0?

A. On Error Goto 0 is used to deliberately switch off the error handler in a function so that you can throw an exception to the calling routine. For example, On Error Goto 0: Err.Raise 32000 will abandon the current function and raise error 32000 in the calling function regardless of any On Error Goto or On Error Resume Next statements in force at the time.

Q. I wrote a DLL in C/C++/Delphi and it crashes my VB program even though I have On Error Goto in every function. Why aren't the errors trapped?

A. DLLs written in other languages donīt generate errors in a way that Visual Basic understands, so it isnīt possible to trap such errors in VB. You should rewrite your DLL to use whatever structured exception handling your language supports and then perhaps use function return codes or output parameters to communicate errors back to VB.

Q. Why is VB error handling so inferior to 'real' programming languages?

A. The main problem with VB exception handling is a consequence of the way VB programs are structured. In a traditional Windows program we have access to the main program loop, which is contained in a single function (called winmain() if weīre writing in C) that every other piece of code can be traced back to. This means that any exception will always propagate back through a single point, and we can trap exceptions with a single exception handler. Unfortunately Visual Basic hides this loop from us and doesnīt allow us to hook an exception handler into it; the result is that we need to write exception handlers for each event handler in our program.

Comparable programming systems such as Delphi, Visual J++ and Visual C++ give us full access to all the code, so we can write single-point exception handlers. (But the penalty is that we need to fiddle with code we didnīt write, which makes programming in these languages more technically demanding.)

VB exception handling is otherwise roughly comparable to exception handling in C++, Java and Delphi, although it isnīt as flexible because we canīt nest exception handlers. VB also lacks the concept of a finally block, which makes writing cleanup code more difficult. You should remember that traditional programming languages like C and Pascal have no exception handling at all!

VB has some other problems that are often wrongly attributed to the exception handling mechanism. These are usually down to `missingī properties or methods on an object. For example, the only way to test whether a Collection (of type VBA.Collection) already contains a particular key is to try to look up that key (or add a new item with the same key) and trap the error. This is a real problem but it is more correctly attributed to the design of the VBA.Collection class (which should probably have an `IsMemberī property).
 

Key Spinner

Đ 1998 - 2009 Mark Hurst. All rights reserved.   Updated March 01, 2009