Unanticipated Errors

When you are designing code to handle errors that may occur in a group of nested procedures, you need to examine calling procedures for errors by tracing the calls list backward. The calls list (sometimes called a procedure invocation path) is the sequence of calls that leads to the currently running procedure; it is displayed in the Calls dialog box.

See Also   For more information on the Calls dialog box, see Chapter 7, “Debugging Visual Basic Code.”

Two different events can occur during the execution of your code that would cause Visual Basic to search back along the calls list for an enabled error handler:

As previously noted, an enabled error handler is one that is turned on by running an On Error statement and that hasn’t yet been turned off, either by an On Error GoTo 0 statement or by exiting the procedure in which it is enabled. An active error handler is one in which code execution is currently taking place. Suppose that the following is the calls list for a group of three nested procedures in your Visual Basic code:

  1. Procedure A is called from a form event.
  2. Procedure A calls Procedure B.
  3. Procedure B calls Procedure C.

If an error occurs in Procedure C and you haven’t enabled error-handling code within that procedure, then Visual Basic searches backward along the calls list first to Procedure B, then to Procedure A, and then to the initial event procedure if necessary. If you haven’t included appropriate error-handling code along the calls list to deal with the error, then Visual Basic displays an appropriate error message and halts execution.

If Visual Basic encounters enabled error-handling code, but the error-handling code’s range of errors doesn’t include the one that has most recently occurred, an unanticipated error can occur within the current procedure. In such a case, the procedure could run endlessly, especially if your error-handling code runs a Resume statement.

To prevent such situations, use the Raise method of the Err object in a Case Else clause. This generates an error within the error handler, forcing Visual Basic to search back farther along the calls list for error-handling code that can deal with the error. This strategy is illustrated in the VerifyFile function included earlier in this chapter.

If Visual Basic finds enabled error-handling code, execution continues with that error-handling code. If the error-handling code includes a Resume or a Resume Next statement, execution continues as shown in the following table.

Statement Result
Resume Visual Basic runs the call to the next procedure in the calls list. Using the example calls list given earlier, if Procedure A has enabled error-handling code that includes a Resume statement, Visual Basic reruns the call to Procedure B.
Resume Next Execution returns to the statement following the last statement run in the current procedure. This is the statement after the call to the next procedure in the calls list. Using the example calls list given earlier, if Procedure A has enabled error-handling code that includes a Resume Next statement, execution returns to the statement in Procedure A after the call to Procedure B.

Important Execution resumes in the procedure where the error-handling code is found, not necessarily in the procedure where the error occurred. If you don’t take this into account when you’re creating error-handling code and nesting procedures, your code may perform in ways you don’t intend, and the behavior of a search backward along the calls list can be hard to predict.