QuickStart: The ErrEx function



 Sept 2010: v2 of VBA Global Error Handler is now available vbWatchdog (no DLLs!)

Overview

The ErrEx function is designed to be used from inside of your global error handling routine as a replacement for the built-in Err function.  It also handles the enabling and disabling of your global error handler and is typically considered the starting point for accessing all the features of the product.

The object that ErrEx returns provides the same properties as Err, but includes these enhancements:


.EnableGlobalErrorHandler (method, see QuickStart: Enabling and disabling (VBA) or QuickStart: Enabling and disabling (VB6))
.DisableGlobalErrorHandler (method, see QuickStart: Enabling and disabling (VBA) or QuickStart: Enabling and disabling (VB6))
.SourceProcedure (read-only property, see Identifying the location of error)
.SourceModule (read-only property, see Identifying the location of error)
.SourceProject (read-only property, see Identifying the location of error)
.SourceLineNumber (read-only property, see Identifying the location of error)
.SourceLineCode (read-only property, see Identifying the location of error)
.State (read/write property, see Changing ErrEx.State to alter the error handling behaviour)
.ShowErrorDialog (method, see Showing the new Vista-style error dialog)
.CallGlobalErrorHandler (method, see Handling errors locally)
.CallStack (method, see QuickStart: Reading the call stack)
.ShowHelp (method, see Other features of ErrEx)
.UserData (read/write property, see Other features of ErrEx)
.IsDebugable (read-only property, see Other features of ErrEx)
.VariablesInspector (VBA edition only, method, see QuickStart: Reading local variables)
.DialogOptions (method, see QuickStart: The Vista-style Error Dialog - Customizing the Vista-style error dialog)
.DLLVersion (read-only property, see Other features of ErrEx)
.VBEVersion (read-only property, see Other features of ErrEx)
.VariablesInspectorEnabled (VBA edition only, read/write property, see Other features of ErrEx)


For a table of all properties and methods, see Reference: ErrEx object properties

Identifying the location of error

The object that ErrEx returns provides five properties for determining the location of the error:

.SourceProcedure (read-only property, string)

        Returns the name of the procedure that caused the error

Information for SimplyVB6 Global Error Handler users:

The SourceProcedure property will contain the name of the procedure that caused the error for all class modules.  However, for standard modules, {Proc #} may be shown instead (where # is a numeric procedure ID) - this is because the names of procedures in standard modules are not included in fully compiled VB6 projects (EXEs/DLLs).  To identify the source procedure of error, lookup the procedure ID in your source code by using our line numbering add-in inside the VB6 IDE.

.SourceModule (read-only property, string)

        Returns the name of the module where the procedure resides

.SourceProject (read-only property, string)

        Returns the name of the VBA project where the procedure resides

.SourceLineNumber (read-only property, long)

        Returns the debug line number of the error. See QuickStart: Automatic line numbering.

.SourceLineCode (read-only property, string)

        Returns the debug line of the error. See QuickStart: Automatic line numbering.

Information for SimplyVBA Global Error Handler users:

Not available in Access MDE files - To identify the exact line of error, cross reference the SourceLineNumber value with your source code using the source line number VBA IDE AddIn provided.

Information for SimplyVB6 Global Error Handler users:

The SourceLineCode property is only valid when debugging in the VB6 IDE.  If you have compiled your project to EXE or DLL format, SourceLineCode will return a blank string since the source code is not available.  To identify the exact line of error, cross reference the SourceLineNumber value with your source code using the source line number VB6 IDE AddIn provided.

Changing ErrEx.State to alter the error handling behaviour

The ErrEx.State property defines what will happen next after your error handler has finished.

Initially, when your error handler is called, the State property indicates what state the local error handling was in before the error occurred. It can be one of five values:

OnErrorGoto0 - indicates no specific error handling has been set (or 'On Error Goto 0')
OnErrorResumeNext - indicates ‘On Error Resume Next’ was set
OnErrorGotoLabel - indicates ‘On Error Goto X’ was set
OnErrorPropagate - indicates ‘On Error Goto X’ was set in a previous procedure in the stack (which will subsequently catch this error)
CalledByLocalHandler - Special case, see Handling Errors Locally

Primarily this property is used to ignore certain errors. For example, to ignore errors that will be caught by a local error handler, one can write the global error handler like this;

Public Sub MyGlobalErrorHandler()

    If ErrEx.State = OnErrorResumeNext Then Exit Sub
    If ErrEx.State = OnErrorGotoLabel Then Exit Sub
    If ErrEx.State = OnErrorPropagate Then Exit Sub

    LogErrorToFile

    MsgBox "An unhandled error has occurred..." & ErrEx.Description '... etc

End Sub

The State property value can also be altered. For example, for debugging purposes you might wish to disable the use of ‘On Error Resume Next’ in your code to find a bug:

Public Sub MyGlobalErrorHandler()

    If ErrEx.State = OnErrorResumeNext Then ErrEx.State = OnErrorGoto0
    
    '...

End Sub

The valid values for State on output are:

OnErrorGoto0 The vista style error dialog will be invoked after your error handler has completed. It is advised to use the ErrEx.ShowErrorDialog method instead though.
OnErrorResumeNext The code will resume at the next line after your error handler has completed
OnErrorGotoLabel The code will resume at the label that was declared in the local procedure after your error handler has completed
OnErrorPropagate (v1.3+) The code will resume at the label that was declared in the previous local procedure after your error handler has completed - see Error Propagation
OnErrorDebug The VBE will break at the line of source code that caused the error after your error handler has completed. Only valid when source code is available. This is the same as the ‘Debug’ button on the standard VBE error dialog. Not available for compiled Access MDE/ACCDE applications, nor compiled VB6 projects - use the ErrEx.IsDebugable property to determine if the debug option is available at runtime.
OnErrorEnd The code will end abruptly after your error handler has completed. Any code that was due to execute immediately after the line that caused the error will not execute. This acts the same as the ‘End’ button on the standard error dialog. For Access MDE/ACCDE applications, this doesn't reset global variables (same behaviour as old VBE).
OnErrorExitProcedure (v1.3.1+) This is the equivalent of using 'Exit Sub' or 'Exit Function' in a local error handler. Tip: using this instead of OnErrorEnd can avoid Access runtime issues where unhandled errors in MDBs/ACCDBs cause Access to close.
CalledByLocalHandler Special case, see Handling Errors Locally
OnErrorRetry (v1.2+) This is the equivalent of using 'Resume' in a local error handler in order to try the repeat the offending line to try again.  Useful for connection time-out issues etc.
Warning: Use this state with caution to prevent a loop forming for permanent errors.

With this functionality, the State property gives you the flexibility to create your own full featured error dialogs. For example, you might want to implement an error dialog for when developing which includes a 'Debug' button, but you probably wouldn't want your end-user clients having these options, so you can implement a different error handler for clients. The Sample.mdb gives you a real example of this scenario and much more.

Showing the new Vista-style error dialog

One of the great features of the Global Error Handler is the customizable Vista-style error dialog. This can be opened using the ErrEx.ShowErrorDialog method. ErrEx.ShowErrorDialog also conveniently returns a value that can be assigned directly to the ErrEx.State property (OnErrorEnd, OnErrorResumeNext, etc)

To open the Vista-style dialog, you can do this:

Public Sub MyGlobalErrorHandler()

    ErrEx.State = ErrEx.ShowErrorDialog()

End Sub

For more details on customizing the Vista-style error dialog, see QuickStart: The Vista-style Error Dialog.

Handling errors locally

To handle errors locally we need to set the global error handler to ignore error states of OnErrorResumeNext, OnErrorGotoLabel and OnErrorPropagate (i.e. leaving the default VBA compatibility in place).

We also use a feature of ErrEx to pass unhandled local errors back on to the global error handler if we decide not to handle the error in the local handler.

Public Sub MyGlobalErrorHandler()

    Select Case ErrEx.State

	Case OnErrorGoto0, CalledByLocalHandler

            ErrEx.State = ErrEx.ShowErrorDialog

    End Select

End Sub

Public Sub Example()

    On Error Goto MyLocalErrorHandler

    Debug.Print 1/0	' Raise an error
    Exit Sub

MyLocalErrorHandler:
    If Err.Number = 11 ' Division by zero error
        Resume Next
    Else
        ErrEx.CallGlobalErrorHandler    ' Call the global error handler
    End If

End Sub

So now we are handling local errors (division by zero in this example) and also passing any unhandled errors back on to the global error handler.

Tip: To obtain a thorough understanding of this approach, the best advice is to copy the above example code into a VBA application, set a break point on it and step through the code line by line.

For taking this a step further and ensuring that all open objects (e.g. recordsets) are closed when an error occurs, see Demo 2 of the Sample.mdb.

Other features of ErrEx

- ShowHelp

This method simply opens the help file associated with the error (as given by ErrEx.HelpFile and ErrEx.HelpContext)

- UserData

Use this Variant storage property if you want to pass an argument to your global error handler from your local procedure code.

This property is automatically cleared after your global error handler next completes.

- IsDebugable

This boolean property should be used when creating your own error dialogs (e.g. by using an Access form).

Use it to determine if you are able to break into the source code at runtime. For example, in MDE compiled Access applications, and VB6 compiled applications, this property will be False. Similarly if the error occurred in the immediate window then this property will be False but for most other times the property value will be True.