Central Error Handlers

[Previous] [Next]

It's tedious to add error handling to all procedures in a project, but it's a necessity. Every unexpected error must be displayed to the user in the same format, and this can take a considerable amount of code. Adding a central error handler can help.

A central error handler is a procedure that you call when an error occurs. At a minimum, a central error handler displays a consistent error message to the user. However, you can add capabilities to the central error handler as you see fit. For instance, you can have your error handler send an e-mail to a support specialist whenever an unexpected error occurs, or you can actually include code to take a snapshot of the state of the machine and log the loaded applications and loaded DLLs, along with their versions.

The following is a typical central error handler:

  FriendSub  ShowError(strModule  AsString  ,strProcedure  AsString  ,_ lngErrorNumber  AsLong  ,strErrorDescription  AsString  )  '*Purpose:Provideacentralerror-handlingmechanism. '*Accepts:strModule-themoduleinwhichtheerrorwas '*encountered(form,class,standard,andsoon.) '*strProcedure-thenameoftheprocedureinwhich '*theerrorwasencountered. '*lngErrorNumber-thenumericidentifierofthe '*error. '*strErrorDescription-thetextdescriptionof '*theerror.   OnErrorGoTo  PROC_ERR  Dim  strMessage  AsString   Dim  strCaption  AsString   '*Buildtheerrormessage.  strMessage="Error:"&strErrorDescription&vbCrLf&vbCrLf&_ "Module:"&strModule&vbCrLf&_ "Procedure:"&strProcedure&vbCrLf&vbCrLf&_ "PleasenotifyMySoftware'stechsupport"&_ "at555-1213aboutthisissue."&vbCrLf&_ "Pleaseprovidethesupporttechnicianwith"&_ "informationshownin"&vbCrLf&"thisdialog"&_ "boxaswellasanexplanationofwhatyou"&_ "were"&vbCrLf&"doingwhenthis"&_ "erroroccurred."  '*Buildthecaptionforthemessagebox.Thecaptionshows '*theversionnumberoftheprogram.  strCaption="UnexpectedError!Version:"&_ Str$(App.major)&"."&Str$(App.minor)&"."&_ Format(App.Revision,"0000") MsgBoxstrMessage,vbCritical,strCaption PROC_EXIT:  ExitSub  PROC_ERR:  ResumeNext   EndSub  

To use this central error handler, you simply call the procedure in an error handler like this:

  PrivateSub  frmMain_Click()  '*Purpose:Generateanerrorbysettingthefocusto '*aninvisiblecontrol.   OnErrorGoTo  PROC_ERR  '*Setthefocustoaninvisiblecontrol.  txtCity.Visible=  False  txtCity.SetFocus PROC_EXIT:  ExitSub  PROC_ERR:  Call  ShowError(Me.Name,"frmMain_Click",Err.Number,Err.Description)  ResumeNext EndSub  

When the error illustrated in the previous example occurs, the central error handler is called and it displays the dialog box shown in Figure 7-4. Imagine trying to display such a comprehensive error message from every error handler in every procedure in every module without using a central error handler!

Notice the use of Me.Name in the ShowError function call, which makes the line of code a bit more portable. You can copy this statement to the Clipboard and paste it into other procedures. In form procedures, all you change is the procedure name. This enables you to write the error handlers in your various procedures more quickly and allows you to change the way errors are handled or displayed by changing code in one location rather than hundreds or thousands of locations.

click to view at full size.

Figure 7-4. A central error handler makes it easy to display comprehensive error messages

For class modules, Me.Name doesn't work, so you have to use the literal class name. However, in this situation it's best to create a module-level constant and use the constant so that you can easily modify the error handlers in a class module when the module's name is changed. If you use a generic constant name, you can copy the Call statements from one module and paste them into another module without having to make major modifications.

Although the central error handler shown earlier displays the error message to the user in a consistent fashion, you must determine the code that each error handler will have in addition to calling the ShowError procedure. For instance, does the error handler require a Resume or a Resume Next statement? Perhaps it requires a GoTo PROC_EXIT statement instead. You should make your error handlers as generic as possible but make sure that each one is appropriate for the procedure in which it resides.

Logging Errors to a Text File

It's often useful to have a log of any errors that occur. For instance, during the testing phase of your project, you need to know as much as you can about any errors that happen. Often, you can't rely on reports from users. When it's critical that you know about every error in your program, you should use a central error handler to create an error log.

Creating an error log is simple. First create a central error handler as discussed earlier. Then, within the central error handler, devise a mechanism to log the errors to a text file. The following code illustrates one way to log errors to a text file. This code is shown as it would appear as part of the central error handler shown previously. It assumes that the local variables in that procedure are present and that there is a global variable in the project called g_strErrorLogFileName that contains the path and name of the error log file.

  Dim  intLogFile  AsInteger   '*Obtainafreefilehandle.  intLogFile=FreeFile  '*OpentheerrorlogtextfileinAppendmode. '*Ifthefiledoesn'texist,theOpenstatement '*createsit.   Open  g_strErrorLogFileName  ForAppendAs  #intLogFile  '*Writetheheader.   Print  #intLogFile,"***ErrorEncountered"&VBA.Now&"***"  '*Writethepertinenterrorinformationtothelogfile.   Print  #intLogFile,"Error:"&lngErrorNumber  Print  #intLogFile,"Description:"&strErrorDescription  Print  #intLogFile,"Procedure:"&strProcedure  Print  #intLogFile,"Module:"&strModule  '*Writeablanklinetothelogfile.   Print  #intLogFile,""  '*Closethelogfile.   Close  #intLogFile 

This code attempts to open the text file specified in the global variable g_strErrorLogFileName in Append mode. If the file doesn't exist, it's created automatically and then opened. Once the file is opened, a log entry is written. In this example, five lines of text are written for each log entry, with each entry separated from the others by a blank line. Here is a sample of a text file created using the previous code:

 ***ErrorEncountered8/29/994:19:18PM*** Error:5 Description:Invalidprocedurecallorargument Procedure:ShowCustomer Module:clsCustomer ***ErrorEncountered8/29/994:20:08PM*** Error:11 Description:Divisionbyzero Procedure:CalculateCoefficient Module:mdlScience ***ErrorEncountered8/29/994:22:05PM*** Error:6 Description:Overflow Procedure:CalculateDrag Module:mdlScience ***ErrorEncountered8/29/994:22:34PM*** Error:11 Description:Divisionbyzero Procedure:CalculateCoefficient Module:mdlScience 

You can start to see a trend in this error log. Whoever wrote the mdlScience module needs to spend a little more time with the code. The information shown here is the minimum amount you'd want to include in a text file; you might want to include much more. For instance, you might want to include the user name of the person running the program when the error occurs, or you might want to include the machine name in the log entry. The possibilities are endless. Whatever you choose to put into the text file, make sure it's pertinent information that will help you find and correct the problem.

For clarity, the following is the complete error handler shown previously, with the inclusion of the error log code:

  FriendSub  ShowError(strModule  AsString  ,strProcedure  AsString  ,_ lngErrorNumber  AsLong  ,strErrorDescription  AsString  )  '*Purpose:Provideacentralerror-handlingmechanism. '*Accepts:strModule-themoduleinwhichtheerrorwas '*encountered(form,class,standard,andsoon.) '*strProcedure-thenameoftheprocedureinwhich '*theerrorwasencountered. '*lngErrorNumber-thenumericidentifierofthe '*error. '*strErrorDescription-thetextdescriptionof '*theerror.   OnErrorGoTo  PROC_ERR  Dim  strMessage  AsString   Dim  strCaption  AsString Dim  intLogFile  AsInteger   '*Obtainafreefilehandle.  intLogFile=FreeFile  '*OpentheerrorlogtextfileinAppendmode. '*Ifthefiledoesn'texist,theOpenstatement '*createsit.   Open  g_strErrorLogFileName  ForAppendAs  #intLogFile  '*Writetheheader.   Print  #intLogFile,"***ErrorEncountered"&VBA.Now&"***"  '*Writethepertinenterrorinformationtothelogfile.   Print  #intLogFile,"Error:"&lngErrorNumber  Print  #intLogFile,"Description:"&strErrorDescription  Print  #intLogFile,"Procedure:"&strProcedure  Print  #intLogFile,"Module:"&strModule  '*Writeablanklinetothelogfile.   Print  #intLogFile,""  '*Closetheerrorlogtextfile.   Close  #intLogFile  '*Buildtheerrormessagefordisplaytotheuser.  strMessage="Error:"&strErrorDescription&vbCrLf&vbCrLf&_ "Module:"&strModule&vbCrLf&_ "Procedure:"&strProcedure&vbCrLf&vbCrLf&_ "PleasenotifyMySoftware'stechsupport"&_ "at555-1213aboutthisissue."&vbCrLf&_ "Pleaseprovidethesupporttechnicianwith"&_ "informationshownin"&vbCrLf&"thisdialog"&_ "boxaswellasanexplanationofwhatyou"&_ "were"&vbCrLf&"doingwhenthis"&_ "erroroccurred."  '*Buildthecaptionforthemessagebox.Thecaptionshows '*theversionnumberoftheprogram.  strCaption="UnexpectedError!Version:"&_ Str$(App.major)&"."&Str$(App.minor)&"."&_ Format(App.Revision,"0000") MsgBoxstrMessage,vbCritical,strCaption PROC_EXIT:  ExitSub  PROC_ERR:  ResumeNext   EndSub  

Once your application is logging error messages, you must decide what you want to do with those logs. If you're on-site with the program, you can manually retrieve copies of the error logs. Or you can have users e-mail you their logs if they encounter problems. You might even write a program that automatically e- mails the logs to you on a preset schedule. Log files can be very useful for locating specific bugs as well as general program errors, and they are easy to create. You should seriously consider adding this feature to your programs. You might even elect to include the code but turn off the feature by default. Then you can enable or disable log file generation via your program's interface or a registry setting.

Goals of Error Handling

The goals of utilizing error handling are

  • Preventing your program from crashing
  • Gracefully correcting mistakes whenever possible
  • Notifying the user when errors occur so that the problems can be addressed


Practical Standards for Microsoft Visual Basic
Practical Standards for Microsoft Visual Basic .NET (Pro-Developer)
ISBN: 0735613567
EAN: 2147483647
Year: 2000
Pages: 57

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net