SimplyVBA and SimplyVB6
Global Error Handler
QuickStart: Error Propagation Sept 2010: v2 of VBA Global Error Handler is now available vbWatchdog (no DLLs!)
On this page you'll find:
This feature requires v1.3+ of the Global Error Handler.
What is Error Propagation?
Let's say we have two procedures - namely Foo and Bar. Foo has local error handling yet Bar does not. Foo calls Bar and Bar generates an exception. Since there is no error handling in Bar, the error 'propagates' back to Foo where it is handled there. This is how error handling works in both VBA and VB6.
Public Sub Foo()
On Error Goto ErrorRoutine
MsgBox "An error has occured in Foo"
Public Sub Bar()
Debug.Print 1 / 0 ' This will force an exception, but will be handled in Foo
How we handle error propagation in our Global Error Handler
In your global error handling procedure you can detect when an error will be propagated back to an earlier procedure in the call stack by examining the ErrEx.State value. In this case, ErrEx.State will equal the constant value OnErrorPropagate.
If when your global error handler exits, the ErrEx.State still equals OnErrorPropagate (i.e. you haven't changed the value) then the code flow will continue at the last procedure in the call stack that has error handling enabled (i.e. 'Foo' in this example).
In other words you don't need to do anything special in order to support error propagation as it complies with how VBA (and VB6) works normally - just be aware of it and how to use it.
Logging details of propagating errors
When a propagating error occurs, you might find it useful to log the source of the error ('Bar' in the example) and also the routine that will ultimately handle the error ('Foo' in the example).
We already have details of 'Bar' as this is at the top of the call stack, so ErrEx.SourceProcedure will give us that.
To find details of the procedure that will ultimately handle the error, we need to find the first match in the call stack that has active error handling - and it's that simple. (Remember that the call stack is backwards - where 'Bar' is the first item, 'Foo' the second etc).
To do this, we use ErrEx.CallStack.HasActiveErrorHandler:
Public Sub MyGlobalErrorHandler()
Select Case ErrEx.State
If .HasActiveErrorHandler = True Then
strErrorWillPropagateTo = .ProjectName & "." & .ModuleName & "." & .ProcedureName
Loop While .NextLevel
Further reading / related pages: