Sub DoSomething()
On Error GoTo CleanFail
DoSomethingElse
CleanFail:
Debug.Print Err.Number
Resume Next
End Sub
If the DoSomethingElse
procedure raises an error, execution jumps to the CleanFail
line label, prints the error number, and the Resume Next
instruction jumps back to the instruction that immediately follows the line where the error occurred, which in this case is the Debug.Print
instruction: the error-handling subroutine is executing without an error context, and when the Resume Next
instruction is reached, run-time error 20 is raised because there is nowhere to resume to.
Sub DoSomething()
On Error GoTo CleanFail
DoSomethingElse
Exit Sub
CleanFail:
Debug.Print Err.Number
Resume Next
End Sub
By introducing an Exit Sub
instruction before the CleanFail
line label, we have segregated the CleanFail
error-handling subroutine from the rest of the procedure body - the only way to execute the error-handling subroutine is via an On Error
jump; therefore, no execution path reaches the Resume
instruction outside of an error context, which avoids run-time error 20.
This is very similar to Run-time error '3': Return without GoSub; in both situations, the solution is to ensure that the normal execution path cannot enter a sub-routine (identified by a line label) without an explicit jump (assuming On Error GoTo
is considered an explicit jump).