On Error Do MyErrHandler With ; ERROR( ), Message( ), Message(1), Program( ), Lineno( ) * ... read events * cleanup code
* MyErrHandler.prg Lparameters tnError, tcMessage, tcMessage1, tcProg, tnLineno * Here it is up tou you where to save this * it could be a free table, a table in your backend, ... a plain file. * suppose a free table in temp folder (in a real world scenario a shared data folder where you have RW access) Local lcErrorTable, lnSelect, lcErrorInfo m.lnSelect = Select() m.lcErrorInfo = GetErrorInfo(m.tnError, m.tcMessage, m.tcMessage1, m.tcProg, m.tnLineno) m.lcErrorTable = Forcepath('MyError.dbf', Sys(2023)) If !File(m.lcErrorTable) Create Table (m.lcErrorTable) Free (Occurred Datetime, Userid c(50), Info m) Endif Insert Into (m.lcErrorTable) (Occurred, Userid, Info) Values (Datetime(), Id(), m.lcErrorInfo) Use in (Select('MyError')) Select (m.lnSelect) * Decide how to proceed here. For simplicity, just showing a message and turning handler off. On Error MessageBox("An error occurred in your program",0+4096,'Error',10000) * cleanup code Procedure GetErrorInfo Lparameters tnError, tcMessage, tcMessage1, tcProg, tnLineno Local lcLog, lcErrorInfo, lcProgStack, lcFile, lcMemory lcProgStack= '' Local Array aStackData[1] Local ix,jx Astackinfo(aStackData) For ix=1 To Alen(aStackData,1) For jx = 1 To Alen(aStackData,2) lcProgStack = m.lcProgStack + Chr(13) + Chr(10) + ; 'aStackData['+; LTRIM(Str(m.ix))+','+; LTRIM(Str(m.jx))+'] = '+Transform(aStackData[m.ix,m.jx]) Endfor Endfor m.lcFile = Forcepath(Sys(2015)+'.dat',Sys(2023)) List Memory Noconsole To File (m.lcFile) m.lcMemory = Filetostr(m.lcFile) Erase (m.lcFile) * Use AERROR() to populate our error array. lcErrorInfo = '' Aerror(laErrors) For ix=1 To Alen(laErrors) lcErrorInfo = m.lcErrorInfo + Chr(13) + Chr(10) + Transform(laErrors[m.ix]) Endfor TEXT TO m.lcLog TEXTMERGE noshow ------------------------------------------------------ DateTime: << Datetime() >> Error:<<m.tnError>> Message:<<m.tcMessage>> Message1:<<m.tcMessage1>> Prog:<<m.tcProg>> Line#:<<m.tnLineno>> ------------------------------------------------------ Details: ------------------------------------------------------ <<m.lcErrorInfo>> ------------------------------------------------------ Program Stack: ====================================================== <<m.lcProgStack>> ====================================================== Memory: ------------------------------------------------------ << m.lcMemory >> ------------------------------------------------------ ENDTEXT Return m.lcLog Endproc