Skip to content

Error management in VBAToolKit

jpimbert edited this page Aug 28, 2013 · 7 revisions

While coding VBAToolKit, we thought it could be nice if errors could work their way up the stack, instead of popping a MsgBox with a low-level error message that users won't understand.

The mechanism

To implement this, we considered the fact that in a called function, an error raised in a subroutine is actually passed to the caller function if it has an error handler.

For example, the following code :

Public Sub caller()  
    On Error GoTo callerErr  
    called
callerErr:  
    MsgBox "Error " & err.Number & " in " & err.Source & " : " & err.Description  
End Sub

Public Sub called()
    err.Raise 3600,"Sub 'called'", "dummy error"
End Sub

will pop a MsgBox displaying "Error 3600 in Sub 'called' : dummy error" when running caller .

It can work with every number of levels.

This example with 3 levels will pop the very same MsgBox :

Public Sub caller()  
    On Error GoTo callerErr      
    called   
callerErr:  
    MsgBox "Error " & err.Number & " in " & err.Source & " : " & err.Description  
End Sub

Public Sub called()
    calledcalled
End Sub

Public Sub calledcalled
    err.Raise 3600,"Sub 'calledcalled'", "dummy error"
End Sub

This allows the filtering of errors rising from the depths of the code to produce custom errors messages relevant to the user.

For example, the code :

Public Sub caller()  
    On Error GoTo callerErr      
    called   
callerErr:  
    MsgBox "Error " & err.Number & " in " & err.Source & " : " & err.Description  
End Sub

Public Sub called()
    On Error GoTo calledErr
    calledcalled
calledErr:
    err.Raise 6666, "Sub 'called'", "Something went wrong."
    Exit Sub
End Sub

Public Sub calledcalled
    err.Raise 3600,"'Sub calledcalled'", "Cryptic error message"
End Sub

will display to the user "Error 6666 in 'Sub called' : Something went wrong.".

Please note that this mechanism has not yet been implemented in the entire project.

Configuration

For the raising mechanism to be effective, VBA has to be configure to not break on errors.
In VBA IDE, select the Options... command of Tools menu.
Be sure that the option Break on Unhandled Errors is selected
Break Errors option

Consequences of this mechanism

For the filtering of errors to be effective, the developer must respect certain guidelines :

  • Errors raised by a function must be at the same "level" than this function. As a consequence, errors must be reinterpreted as they work their way up the stack. For example, an error during the creation of a folder in a low-level function would appear as an initialization error to the "user-level" function.

  • A function must only raise a limited range of errors. When an error occurs but has not been foreseen, the function should raise a VTK_UNEXPECTED_ERROR but keep the err.Description so as to allow potential understanding and debugging.

  • The "user-level" functions, the ones connected to the forms and listed in the module vtkMainFunctions, are the only ones that should pop a MsgBox. Lower-level functions are not supposed to communicate with the user. No need for these functions to explicitly call MsgBox in an error handler; A message box is the default behavior since there is no error handler at the very top level.

  • Controllers in the forms should, as much as possible, filter the parameters sent to the main functions. For example, CreateProjectForm displays colors to signal illicit parameters and only activates the "Create" button when the parameters are right.

Where errors are declared

The errors are declared in vtkConstants.bas.

Each one is declared with the statement :

Public Const VTK_XXXXXX = 1234