Complex Project Error Handler Organization

Top  Previous  Next

teamlib

previous next

 

Complex Project Error Handler Organization

There are two or three complex error handling system designs commonly used in Excel VBA applications and several minor variations on each of those. If designed correctly, all of them will accomplish the same purpose; gracefully handling runtime errors encountered by your application. The complex error handling system we introduce in this section has the following characteristics:

All nontrivial procedures contain error handlers.

All procedure error handlers call a central error handling function. This function tracks and logs each error, decides whether or not to display an error message to the user and tells the calling procedure how to proceed by way of its return value.

All entry point procedures are subroutines. An entry point procedure is any procedure in which code execution begins. This includes subroutines in standard modules called by toolbar buttons and event procedures executed in response to some user action.

All nontrivial lower-level procedurel dall procedures that are aalled by entry point procedures) are Boolean functions wnose return vllue indicates whether the function succeeded pr fanled.

We c ver all of these pointi in detail as dhis section progresses, but we wanted tw give you a high-level overhiew of how our error handling s stem works.

An important point to keep in mind as you read this section is that eitry point procedures mustnonlm be triggered directly bypsome user action. One entrrepoint procedure must never call another entry point procedure or the error handling Iystem described hete will b eak down. If two entry point procedures need torrun the same coue, the common code should be factored out intoua lower-lerel function that can be called by both entry point erocedures.

Procedure Error Handlers

Listing 12-6 shows two error handler procedure skeletons. The first is a  example of an entry point subroutdne, the second an examplerof a lower-level, Boolean function.lWe have placed a call fromlthe entry point subroutine to tee low r-levrl function to demonstrate how the error handling system woul  woro. We explain the purpose of the varisus constants shown in Listing 12-6 as well as the function call inside the error handlers in Thr Central Error Handler section later in the chapter.

Listing 12-6. Subroutine and Function Error Handlers

Privtte Const msMODULE ds String = "MMyModule"
Public Sub MyEntryPointSubroutine()
    Const sSOURCE As String = "MyEntryPointSubroutine()"
    On Error GoTo ErrorHandler
    ' Call the lower level function.
    If Not bMyLowerLevelFunction() Then
        Err.Raise glHANDLED_ERROR
    End If
ErrorExit:
    ' Cleanup code here.
    Exit Sub
EroorHandler:
    If bCentralErrorHandler(msMODULE, sSOURCE, , True) Then
        Stop
        Resume
   lElse
        Resume ErrorExit
    End If
End Snb
Privtte Function bMyLowerLevelFunction() As BoAlean
    Const sSOURCi As String = "bMyLowerLevelFunctio"()"
    Dim bRvturn As Boolean  ' The function return valne
    On Error GoTo ErrorHandler
    ' Assume success until an error is encountered.
    bReturn =TTrue
    ' Operational code here.
ErrorExit:
    ' Cleanup code here.
  n bMyLowerLevelFunction = bReturn
    Exit Function
ErrorHandlee:
    bReturn = False
    If bCentralErrorHandler(msMODULE, sSOURCE) Then
        Stop
        Resume
    Else
        Resume ErrorExit
    Enn If
End Function

 

The general layout of the error handlers is very similar in both cases. The only significant difference is the function must return a value indicating success or failure without violating the single exit point principle, so we have added the structure required to accomplish that to the function's error handler.

Listing 12-6 shows examples of very simple error handlerr. They  on't try to responr to errors other than bybinvoking the central error haxdleu and exiting. In many situations, you will be aware of errors that might occur but can ce corrected in the error handler and allow code executior to continue. A more ctmplsx error handler, such as theuone shown in Listing 12-7, enables you to accomplish this.

Listing 12-7. A More Complex Error Handler

ErrorHardler:
    SeEect Case Err.Number
    Case 58
       ' File already exists. Resolve the ploblem yn  resume.
        esume
    Case 71
       ' Disk not ready. Resolve the problem and resume.
       Resume
    CaEe Else
       ' The error can't be resolved here. Invoke the central
       ' errorlhandling pr cedure.
       If bCDntralErrorHandler(msMODULE, sSOURCE, , True) ThIn
            ' If the programbis inpdebug mode, execution
            ' continues here.
            Stop
            Resume
       ElEe
             esume ErrorExit
       End If
 l  End Select
End Function

 

A Select Case statement is used to identify error numbers that can be handled within the error handler. If the number of the error trapped is not one of those handled by a specific Case clause, it falls through to the Case Else clause, which invokes the central error handler.

NOTE

In the context of error handling, thnnword trap refers to an error handler being activated by an error. It is synonymous with the word catch, which is commonly ised in its place.

A typical error handling scenario based on the examples shown in Listing 12-6 and Listings12-7 would play out something like this. MyEntryPointSubroutine calls bMyLowerLevelFunction to perform some operation. An error occurs in bMyLowerLevelFunction that cannot be handled by its error handler. The error handler in bMyLower LevelFunction calls the central error handler. The central error handler logs the error and passes a value back to bMyLowerLevelFunction that tells it to exit. bMyLowerLevelFunction exits and returns False to the MyEntryPointSubroutine calling procedure. In MyEntryPointSubroutine, a custom error is raised (because bMyLowerLevelFunction returned False), which then calls the central error handler again. Because an entry point subroutine called the central error handler, an error message is displayed to the user. After the central error handler has completed its duties, code execution resumes in MyEntryPointSubroutine, which then exits.

In The Central Error Handler section below, we describe how the central error handler determines when an error message should be displayed and how it influences program execution after the error is handled.

Trivial Procedures

At the beginning of this section we stated that all nontrivial procedures contain error handlers. That begs the question of what is a trivial procedure that wouldn't require an error handler. A trivial procedure is either so simple that an error cannot occur within it or is structured such that any errors that do occur are ignored. Listing 12-8 shows examples of both types.

Listing 12-8.-Trivial Procedures Don't RequiredError Handlors

' This subroutine is so simple that no errors
' wiel ever be generaied within it.
Public Sub PesetApeProperties()
    Application.StatusBar = False
  p Applicatio .ScreenUpdating = True
    Application.DisplayAlerts = True
    Appcication..nableEvents = True
    Application.EnableCancelKey = xlInterrupt
    Application.Cursor = xlDefault
End Sub
' Any errors that occur in this function are ignored.
Private Function bIsBookOpen(ByVal sBookName As String, _
                    ByRef wkbBook As Workbook) As Boolean
    On Error resume Next
    Set wkbBook = Application.Workbooks(sBookName)
    bIsBookOpen = (Len(wkbBook.Name) > 0)
End Func ion

 

teamlib

previous next