You can use this Errorsys.prg
You can replace the spanish & italian comments included on it with your own.
/***
* Errorsys.prg
* Standard Clipper error handler
* Copyright (c) 1990-1993, Computer Associates International, Inc.
* All rights reserved.
* Compile: /m /n /w
*/
#include "error.ch"
#include "setcurs.ch"
#include "set.ch"
#include "Fileio.Ch"
// put messages to STDERR
#command ? <list,...> => ?? Chr(13) + Chr(10) ; ?? <list>
#command ?? <list,...> => OutErr(<list>)
// used below
#define NTRIM

(LTrim(Str

))
#define VERO .T.
#define FALSO .F.
/***
* DefError()
*/
static func DefError(e)
local i, cMessage, aOptions, nChoice
LogError(e)
// by default, division by zero yields zero
if (e:genCode == EG_ZERODIV)
return (0)
end
// for network open error, set NETERR() and subsystem default
if (e:genCode == EG_OPEN .and. e

sCode == 32 .and. e:canDefault)
NetErr(.t.)
return (.f.) // NOTE
end
// for lock error during APPEND BLANK, set NETERR() and subsystem default
if (e:genCode == EG_APPENDLOCK .and. e:canDefault)
NetErr(.t.)
return (.f.) // NOTE
end
// build error message
cMessage := ErrorMessage(e)
// build options array
// aOptions := {"Break", "Quit"}
aOptions := {"Quit"}
if (e:canRetry)
AAdd(aOptions, "Retry"

end
if (e:canDefault)
AAdd(aOptions, "Default"

end
// put up alert box
nChoice := 0
do while (nChoice == 0)
if (Empty(e

sCode))
nChoice := Alert(cMessage, aOptions)
else
nChoice := Alert(cMessage +";(DOS Error " + NTRIM(e

sCode) + "

",aOptions)
endif
if (nChoice == NIL)
exit
endif
enddo
if (!Empty(nChoice))
// do as instructed
if (aOptions[nChoice] == "Break"

Break(e)
elseif (aOptions[nChoice] == "Retry"

return (.t.)
elseif (aOptions[nChoice] == "Default"

return (.f.)
endif
endif
// display message and traceback
if (!Empty(e

sCode))
cMessage += " (DOS Error " + NTRIM(e

sCode) + "

"
end
? cMessage
i := 2
while (!Empty(ProcName(i)))
? "Called from", Trim(ProcName(i)) + "(" + NTRIM(ProcLine(i)) + "

"
i++
enddo
// give up
ErrorLevel(1)
QUIT
return (.f.)
*--------------------------
static func ErrorMessage(e)
local cMessage
cMessage := if(e:severity > ES_WARNING, "Error ", "Warning "

if (ValType(e:subsystem) == "C"

// add subsystem name if available
cMessage += e:subsystem()
else
cMessage += "???"
endif
if (ValType(e:subCode) == "N"

// add subsystem's error code if available
cMessage += ("/" + NTRIM(e:subCode))
else
cMessage += "/???"
endif
if (ValType(e:description) == "C"

// add error description if available
cMessage += (" " + e:description)
endif
// add either filename or operation
if (!Empty(e:filename))
cMessage += (": " + e:filename)
elseif (!Empty(e

peration))
cMessage += (": " + e

peration)
endif
return (cMessage)
*+++++++++++++++++++++++++++++
* OBJETO Err - Objeto clase ERROR pasado por CLIPPER
STATIC FUNCTION LogError(Err)
LOCAL screen := SAVESCREEN(0,0,MAXROW(), MAXCOL())
LOCAL LogFile := GETENV("LOG_FILE"

LOCAL errat := SELECT()
LOCAL vname, vtype, vrec, memcount, scount, memhandle, fhandle, x
LOCAL memlength, count, vars, bytes, memwidth, ttemp, atemp, i
LOCAL start, j, range, outstring, substring
// Set default File log
IF EMPTY(LogFile)
LogFile='ERRORLOG'
ENDIF
// Error division por zero, por default devuelve 0
IF (Err:genCode == EG_ZERODIV)
RETURN(0)
ENDIF
// Error de OPEN en la red, set NETERR() y el subsistema di default
IF (Err:genCode == EG_OPEN .AND. Err

sCode == 32 .AND. Err:canDefault)
NetErr(VERO)
RETURN(FALSO)
ENDIF
// Error de LOCK durante APPEND BLANK, set NETERR() y el subsistema por default
IF (Err:genCode == EG_APPENDLOCK .AND. Err:canDefault)
NetErr(VERO)
RETURN(FALSO)
ENDIF
// Error de Impresora NO EN LINEA
IF (Err:subsystem == "TERM"

ALERT("La Impresora no esta en linea"

RETURN(VERO)
ENDIF
IF .NOT. FILE(LogFile)
fhandle := FCREATE(LogFile, FC_NORMAL)
ELSE
fhandle := FOPEN(LogFile, FO_READWRITE + FO_EXCLUSIVE)
ENDIF
FSEEK(fhandle, 0, FS_END) // Colocar puntero al final del archivo
IF fhandle < 4 .AND. !EMPTY(FERROR()) // Imposible escribir en el LOGFILE
ALERT("Error : Se ha verificado un Error de sistema"

ELSE
// Memorizo el estado del programma en el LOGFILE
*ÍÍ Intestazione Error ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
Fwriteline(fhandle, PADR("ÍÍÍ Inicio ErrorLog File", 79, "Í"

)
Fwriteline(fhandle, "Error en funcion: " + PROCNAME(4))
Fwriteline(fhandle, "Fecha: " + DTOC(DATE())+" Hora: " + TIME())
Fwriteline(fhandle, "Mem. disponible: " + Strvalue(MEMORY(0))+"Kb"

Fwriteline(fhandle, " Archivo actual: " + Strvalue(SELECT()))
*ÍÍ Informacion generica del Error ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
Fwriteline(fhandle, ""

Fwriteline(fhandle, PADR("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Informacion especifica del Error ", 79, "¯"

)
Fwriteline(fhandle, ""

Fwriteline(fhandle, " Subsistema: " + Err:subsystem())
Fwriteline(fhandle, " Codigo de Error: " + Strvalue(Err:subcode()))
// Fwriteline(fhandle, " Default Status: " + Strvalue(Err:candefault))
Fwriteline(fhandle, " Descripcion: " + Err:description())
Fwriteline(fhandle, " Operacion : " + Err

peration())
Fwriteline(fhandle, " Codigo Error DOS: " + Strvalue(Err

scode()))
*ÍÍ Rastreo del procedimiento ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
Fwriteline(fhandle, ""

Fwriteline(fhandle, PADR("¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Seguimiento ", 79, "¯"

)
Fwriteline(fhandle, ""

i := 1
DO WHILE !EMPTY(PROCNAME(++i))
Fwriteline(fhandle, PADR(PROCNAME(i), 20) + ": " + PADR(PROCLINE(i), 20))
ENDDO
FWRITE(fhandle, CHR(13)+CHR(10))
*ÍÍ Informacion Area de Trabajo ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
Fwriteline(fhandle, ""

Fwriteline(fhandle, PADR("¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Informacion del Area de Trabajo ", 79, "Ä"

)
Fwriteline(fhandle, ""

FOR x := 1 TO 250
SELECT(x)
IF !EMPTY(ALIAS())
Fwriteline(fhandle, " Alias: " + ALIAS())
Fwriteline(fhandle, " Registro actual: " + Strvalue(RECNO()))
Fwriteline(fhandle, " Filtro activo: " + DBFILTER())
Fwriteline(fhandle, " Relacion activa: " + DBRELATION())
Fwriteline(fhandle, " Clave activa: " + INDEXKEY(INDEXORD()))
Fwriteline(fhandle, ""

ENDIF
NEXT
*ÍÍ Memoria disponible para variables ÍÍÍÍÍÍÍÍÍÍÍÍÍ*
Fwriteline(fhandle, PADC(" Memoria disponible para variables", 80, "+"

)
Fwriteline(fhandle, ""

SELECT(errat)
SAVE ALL LIKE * TO Errormem
memhandle := FOPEN("Errormem.mem", FO_READWRITE)
memlength := FSEEK(memhandle, 0, FS_END)
FSEEK(memhandle,0)
count := 1
bytes := vars := 0
DO WHILE FSEEK(memhandle, 0, FS_RELATIVE)+1 < memlength
memwidth := SPACE(18)
// Leer la Informacion de la variable
FREAD(memhandle, @memwidth, 18)
vname := LEFT(memwidth, AT(CHR(0), memwidth)-1)
vtype := SUBSTR(memwidth, 12, 1)
vrec := BIN2W(RIGHT(memwidth,2))
IF(vtype $ CHR(195)+CHR(204), memcount := 14+vrec, memcount := 22)
FSEEK(memhandle, memcount, FS_RELATIVE)
ttemp := LEFT(vname + SPACE(10), 10)
ttemp += " TYPE " + TYPE(vname)
ttemp += " " + IF(TYPE(vname) = "C", ["] + &vname + ["], Strvalue(&vname))
IF TYPE(vname) = "C"
bytes += (atemp := LEN(&vname.))
ELSEIF TYPE(vname) = "N"
bytes += (atemp := 9)
ELSEIF TYPE(vname) = "L"
bytes += (atemp := 2)
ELSEIF TYPE(vname) = "D"
bytes += (atemp := 9)
ENDIF
FWRITE(fhandle, " " + TRANSFORM(atemp, "9999999"

+ "bytes -> "

Fwriteline(fhandle, " " + ttemp)
ENDDO
FCLOSE(memhandle)
FERASE("Errormem.mem"

FCLOSE(fhandle)
*ÍÍ Box de aviso al operador ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ*
ALERT("ATENCION: Se a verificado un Error. ;"+ ;
" Se ruega comunicar el siguiente dato a la;"+ ;
" Asistencia Tecnica: ;"+ ;
" ;"+ ;
" SubSistema: " + PADR(Err:subsystem(), 30)+';' + ;
" Codigo de Error: " + PADR(LTRIM(STR(Err:subcode())), 30)+';'+ ;
" Descripcion: " + PADR(Err:description(), 30)+';'+ ;
" Operacion: " + PADR(Err

peration(), 30)+';'+ ;
" Error DOS: " + PADR(LTRIM(STR(Err

scode())), 30)+';'+ ;
" Nombre Programa: " + PADR(PROCNAME(4), 30)+';'+ ;
" Linea programa: " + PADR(LTRIM(STR(PROCLINE(4))), 30))
ENDIF
// Salida forzada preparando el ambiente para el DOS
ERRORLEVEL(1)
DBCLOSEALL()
SETCURSOR(SC_NORMAL)
SET COLOR TO
SETBLINK(.T.)
CLS
QUIT
RETURN(FALSO)
*----------------
STATIC FUNCTION Strvalue(string, onoff)
LOCAL retval := ""
onoff := IF(onoff == NIL, FALSO, onoff)
DO CASE
CASE VALTYPE(string) = "N" ; retval := LTRIM(STR(string))
CASE VALTYPE(string) = "M"
retval := IF((LEN(string) > (MEMORY(0) * 1024) * .80), SUBSTR(string,1, INT(MEMORY(0)*1024*.80)),string)
CASE VALTYPE(string) = "D" ; retval := DTOC(string)
CASE VALTYPE(string) = "L"
retval := IF((onoff), IF(string, "On", "Off"

, IF(string, "Vero", "Falso"

)
ENDCASE
RETURN(retval)
*---------------
STATIC FUNCTION Fwriteline(handle, string)
FWRITE(handle, string + CHR(13)+CHR(10))
RETURN(NIL)
*-----------