Reputation: 97
I'm trying this time to handle errors between nested subs. For example:
Sub A()
On Error GoTo errormsg
Call B
Call C
Exit Sub
errormsg:
MsgBox "Error in A", vbOKOnly, "Warning"
End Sub
Sub B()
On Error GoTo errormsg
Call D
Exit Sub
errormsg:
MsgBox "Error in B",vbOKOnly,"Warning"
End Sub
Sub C()
On Error Goto errormsg
'...
Exit Sub
errormsg:
MsgBox "Error in C",vbOKOnly,"Warning"
End Sub
Sub D()
On Error GoTo errormsg
'...
Err.Raise 6 'overflow error
'...
Exit Sub
errormsg:
MsgBox "Error in D",vbOKOnly,"Warning"
End Sub
Well, If there is an error when calling D from B(from A), ErrorD shows, but not ErrorB neither ErrorA. What am I doing/understanding wrong?
Thanks a lot in advance
Upvotes: 1
Views: 86
Reputation: 71217
On Error GoTo [error-handler-label]
tells VBA to jump to the specified label whenever a runtime error occurs in a method. When you use error handlers, you're telling VBA "it's all good, no need to blow everything up, I can handle it". So when Sub D
runs:
Sub D() On Error GoTo errormsg '... Err.Raise 6 'overflow error '... Exit Sub errormsg: MsgBox "Error in D",vbOKOnly,"Warning" End Sub
When execution reaches the line that throws an error, VBA jumps to the errormsg
label and you should see the "Error in D" message. Then execution returns to the caller (Sub B
) and, as far as the runtime is concerned, the error that was raised in D was taken care of (because you told it "I'll handle it" with that On Error
statement), so execution resumes with the Exit Sub
statement and returns to Sub A
to run Sub C
.
If you want runtime errors to "bubble up", you either need to re-raise them in the error handling subroutine:
Err.Raise Err.Number 'per Err.Raise specs, current Err values are reused when only the Number parameter is specified
...Or you remove the handler in Sub D
and decide to handle it higher up in the call stack. For example, if you remove all handlers except in Sub A
, then you will see "Error in A" with the error message actually being that of the error that was raised in Sub D
- unfortunately without any way of telling where in the call stack that error occurred, because VBA doesn't expose its call stack.
Re-raising the error in every error handler should pop the follow messages, in that order:
Upvotes: 2