Catch Your Errors in Style
by Steve Workings
Originally published in Alpha Forum
Posted at www.workings.com January 21, 2001

OK, how many of you out there know how to catch and handle an error in Alpha Five? (A few hands go up). Now, of those who raised their hands, how many of you regularly include full error handling routines in your applications (Most, if not all hands go down.)

This is for everyone whose hand is not in the air after both of those questions have been asked.

Take a look at pages 273-277 of the Alpha Five Professional Edition Reference. Sure, that tells you a little about errors and how to handle them, and if nothing else you should start with the basic implementation illustrated in those examples. But I want to show you what just a little bit more work can do.

Let’s look at one of my very basic scripts that simply closes the parent form (the main menu in this case) and then closes Alpha Five:

' Main Menu Close Button onPush Event
' Logout and close
' by Steve Workings
' 11-27-1997
' -----------------------------
on error goto error_handler
dim global userid as c
parent.close()
:A5.close()
end

error_handler:
script_play("scpAdminErrorHandler")

This isn’t fancy, but it shows a standard implementation of an error handler. The difference between this script and the one in the book is that when an error occurs, a script called "scpAdminErrorHandler" will play. So, it’s logical to look next at the contents of that script:

error_handler:
dim global userid as c
dim shared proc as c
dim shared msg as c
tbl = table.current()
err = error_code_get()
errstr = ltrim(str(err))
msg = error_text_get(err)
table = a_db_current
form = a_form_current
mode = ltrim(str(tbl.mode_get()))
obj = this.name()

ui_msg_box("A Problem Has Occurred", "Please make note of this:" + chr(10) + chr(10) + "Code: " + errstr + chr(10) + "Descrip: " + msg + chr(10) + "Table: " + table + chr(10) + "Form: " + form + chr(10) + "Mode: " + mode + chr(10) + "Object: " + obj + chr(10) + chr(10) + "Date/Time: " + dtoc(date()) + " at " + left(time(),5) + chr(10) + chr(10) + "Suggestion: If this problem persists, please bring the information above" + chr(10) + "to the attention of the administrator." + chr(10) +chr(10) + "This information has been automatically recorded.", 48)

tbl_err = table.open(a_db_current_path + "zzlogerror", file_rw_shared)
tbl_err.enter_begin()
tbl_err.errtime = time()
tbl_err.errdate = date()
tbl_err.errusername = userid
tbl_err.errnumber = err
tbl_err.errdescription = msg
tbl_err.errtable = table
tbl_err.errform = form
tbl_err.errmode = mode
tbl_err.errobject = obj
tbl_err.enter_end(.t.)
tbl_err.close()
resume next

Now, this isn’t as complicated as it looks. Let’s break it down into it’s pieces:

After a few DIM statements, the script assigns values to several variables. In order, they are:

err = error_code_get()
Gets the error code number

errstr = ltrim(str(err))
converts the error code to a character string for later use

msg = error_text_get(err)
gets a text message associated with the error code

table = a_db_current
returns the name of the path and table in use at the time of the error.

form = a_form_current
returns the name of the current form.

mode = ltrim(str(tbl.mode_get()))
returns the user mode (
Change, Enter or View).

obj = this.name()
returns the name of the object that contains the parent script.

OK, so now that we have this information, what shall we do with it? How about first displaying it for the user?

That’s what the really long ui_msg_box command does -- it puts all the variables into a useful and informative message for the user to see. Figure 1 is a sample message box generated by this script.


Figure 1 - The custom error message ui box.

And finally, why not record this information in a table for future reference? That’s what the final set of commands do -- they open a table called zzlogerror.dbf and enter a new record with the information we’ve already gathered along with the time and date of the record. Figure 2 shows the form I use to view the error log.


Figure 2 - A view of the data recorded by the error handler.

Be cautioned that this is only one of several error handling routines I use. You can see by the last line in scpAdminErrorHandler that I tell the script to resume after reporting the error. This would be a disaster in, say, an accounting function where you may not only want to stop the script but return the data to it’s original state before the error-containing process was run.

But put an error handling routine like this in EVERY script -- I mean every one of them. And then just wait for some user to walk up and complain loudly in front of you and your boss about how many errors he’s getting. If he’s wrong then you will have the hard evidence to show the boss that Mr. Loudmouth is getting far fewer problems than he proclaims. And if you use the information in the error log intelligently, you’ll have far fewer complaints in the first place because you’ll be right on top of the problems and solving them much more quickly.

###