Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Suggest some good error handling code
Message
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00596176
Message ID:
00596273
Views:
23
>Can someone suggest some good error handling code

I have an error handler method that logs some important information to a text file (with the file name [application name]+.ERR). I chose a text file because in case of error I prefer to work with low level functions and not to switch datasessions and/or work areas.

(You should use the new Textmerge functions instead of the low level file functions.)

I also do not show any errors that could occur in the error handler itself, because that would be confusing.

I place the method into the main application object, but of course you could create an error object that has more encapsulated behavior (would be better).

I also show the error to the user, depending on the setting in the application object (ShowErrors = .T.). I also have a property on this object that gives me the number of the last occurred error.

At startup of the program I set the error handler on:

ON ERROR poAppContr.HandleError(Program(), LineNo(), Alias(), Message(), Error())

The method itself:

LPARAMETERS tcProgram, ;
tnLineNr, ;
tcAlias, ;
tcMessage, ;
tnError
*
LOCAL lnSel, ;
lnSetMemo, ;
llNewFile, ;
lcOldErr, ;
llErr, ;
lnErrFile, ;
lnNr, ;
lcLine
*
lcOldErr = ON("ERROR")
lnSel = SELECT()
lnSetMemo = SET("MEMOWIDTH")
*
*-- Before anything else we want to set a property what the
*-- error # was that occured so we can access it from other
*-- objects.
THIS.LastErrorNr = tnError
*
SET MEMOWIDTH TO 5000
*
*-- First store the local memory variables and then the
*-- private variables and then the parameters into
*-- text files. (We use the prefixes l, p and t for Local
*-- variables, Private variables and Properties respectively).
DISPLAY MEMORY LIKE l* TO FILE Locals.TXT NOCONSOLE
DISPLAY MEMORY LIKE p* TO FILE Private.TXT NOCONSOLE
DISPLAY MEMORY LIKE t* TO FILE PARAMS.TXT NOCONSOLE
*
*-- Create a cursor that keeps this information.
CREATE CURSOR CMemos (Locals M, Privates M, Params M)
APPEND BLANK
APPEND MEMO Locals FROM Locals.TXT
APPEND MEMO Privates FROM Private.TXT
APPEND MEMO Params FROM Params.TXT
*
*-- Clean up the files right away.
ERASE Locals.TXT
ERASE Private.TXT
ERASE Params.TXT
*
*-- We do not want any errors in the error handler.
ON ERROR llErr = .F.
*
*-- Check if error log file exists and recreate or not.
IF FILE(THIS.oActiveDBC.DataPathName + "ErrorLog.TXT")
lnErrFile = FOPEN(THIS.oActiveDBC.DataPathName + "ErrorLog.TXT", 2)
ELSE
lnErrFile = FCREATE(THIS.oActiveDBC.DataPathName + "ErrorLog.TXT")
ENDIF
*
IF lnErrFile > -1
*
FSEEK(lnErrFile,0,2)
FPUTS(lnErrFile, PADR("",43,"*") )
FPUTS(lnErrFile, "ErrorNr: " + ALLTR(STR(tnError)) )
FPUTS(lnErrFile, "Message: " + ALLTR(MESSAGE()))
FPUTS(lnErrFile, "Method: " + tcProgram)
FPUTS(lnErrFile, "Line nr: " + ALLTR(STR(tnLineNr)))
FPUTS(lnErrFile, "Alias: " + IIF(EMPTY(tcAlias), "", tcAlias))
FPUTS(lnErrFile, "Date: " + DTOC(DATE()))
FPUTS(lnErrFile, "Time: " + TIME())
FPUTS(lnErrFile, "User: " + THIS.oUser.UsID)
*
SELECT CMemos
*
*-- Append memory information.
FPUTS(lnErrFile, "Locals: ")
FOR lnNr = 1 TO MEMLINES(Locals)
lcLine = MLINE(Locals, lnNr)
*-- We do not want the variables that we created in
*-- this method to appear in the list of variables.
IF "handleerror" $ lcLine = .F. AND !EMPTY(lcLine)
FPUTS(lnErrFile, lcLine)
ENDIF
ENDFOR
FPUTS(lnErrFile, "Privates: ")
FOR lnNr = 1 TO MEMLINES(Privates)
lcLine = MLINE(Privates, lnNr)
*-- We do not want the variables that we created in
*-- this method to appear in the list of variables.
IF "handleerror" $ lcLine = .F. AND !EMPTY(lcLine)
FPUTS(lnErrFile, lcLine)
ENDIF
ENDFOR
FPUTS(lnErrFile, "Params: ")
FOR lnNr = 1 TO MEMLINES(Params)
lcLine = MLINE(Params, lnNr)
*-- We do not want the variables that we created in
*-- this method to appear in the list of variables.
IF "handleerror" $ lcLine = .F. AND !EMPTY(lcLine)
FPUTS(lnErrFile, lcLine)
ENDIF
ENDFOR
ENDIF
*
*-- Release the file handle.
FCLOSE(lnErrFile)
*
*-- Restore setting.
SELECT (lnSel)
SET MEMOWIDTH TO (lnSetMemo)
ON ERROR &lcOldErr
*
*-- We show our error message always in the devmode,
*-- or when the THIS.ShowErrors = .T. which could be reset
*-- by some methods.
IF THIS.ShowErrors = .T. ;
OR THIS.DevMode = .T.
lnMessRetVal = THIS.oUtils.DoMessage;
("An error occured in the Program:" + ;
CHR(13) + L("ErrorNr:") + " " + ALLTR(STR(tnError)) + ;
CHR(13) + L("Message:") + " " + ALLTR(tcMessage) + ;
CHR(13) + L("File:") + " " + ALLTR(tcProgram), ;
"*_Ignore*Quit*", "X")
*
*-- If you quit.
IF lnMessRetVal = 2
*-- Since we may now quit from any point in
*-- the application we do not use CloseApp.PRG because
*-- CloseApp.PRG will try to close all windows and clear
*-- events but this may be impossible now. We have had
*-- several situations that CloseApp.PRG did not work
*-- from the error handler.
CANCEL
ENDIF
ENDIF
*
RETURN .T.

Christian Isberner
Software Consultant
Previous
Reply
Map
View

Click here to load this message in the networking platform