ON ERROR poAppContr.HandleError(Program(), LineNo(), Alias(), Message(), Error())
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.