Here is a very rough example:
[tt]
#DEFINE crlf CHR(13)+CHR(10)
SET FULLPATH OFF
ON ERROR DO Err_Handler WITH ERROR(), MESSAGE(), MESSAGE(1), PROG(), SYS(16)
* Cause 1st error
? NonExistantVar1
DO SubProc
LOCAL oForm
oForm = CREATEOBJECT("MyForm"

oForm.SHOW(1)
ON ERROR
PROCEDURE SubProc
* Cause 2nd error
? NonExistantVar2
ENDPROC
PROCEDURE Err_Handler(lnErrNum, lcErrMsg1, lcErrMsg2, lcErrProg, lcSysProg)
MESSAGEBOX( ;
"Error number: "+TRANSFORM(lnErrNum)+crlf+;
"Error message: "+lcErrMsg1+crlf+;
"Error message param: "+lcErrMsg2+crlf+;
"Prog or method that caused error: "+lcErrProg+crlf+;
"Sys prog: "+lcSysProg, ;
48, ;
"Error - Trapped by global error handler!" ;
)
ENDPROC
DEFINE CLASS MyForm AS FORM
DOCREATE = .T.
AUTOCENTER = .T.
ADD OBJECT cmdError1 AS COMMANDBUTTON WITH ;
TOP = 10, ;
LEFT = 10, ;
HEIGHT = 27, ;
WIDTH = 84, ;
CAPTION = "Click to trap error with global error handler", ;
AUTOSIZE = .T.
ADD OBJECT cmdError2 AS COMMANDBUTTON WITH ;
TOP = THIS.cmdError1.TOP+THIS.cmdError1.HEIGHT+10, ;
LEFT = 10, ;
HEIGHT = 27, ;
WIDTH = 84, ;
CAPTION = "Click to trap error with local error handler", ;
AUTOSIZE = .T.
PROCEDURE cmdError1.CLICK
* Cause 3rd error
? NonExistantVar3
ENDPROC
PROCEDURE cmdError2.CLICK
* Cause 4th error
? NonExistantVar4
ENDPROC
PROCEDURE cmdError2.ERROR
LPARAM nError, cMethod, nLine
MESSAGEBOX( ;
"Error number: "+TRANSFORM(nError)+crlf+;
"Method that caused error: "+cMethod+crlf+;
"Error line in method: "+TRANSFORM(nLine), ;
48, ;
"Error - Trapped by local error method" ;
)
ENDPROC
ENDDEFINE
[/tt]
'We all must do the hard bits so when we get bit we know where to bite'
