14.9 Error Hooks
At the instigation of Andrej Falout, Mike Aubury has altered error handling in Aubit4GL.
Now when an error occurs (other than one which causes a core dump or is the result of EXIT PROGRAM), the program calls a function errlog() in a shared (i.e. dynamically linked) library.
To customise error handling you do the following:
-
write a function errlog() as per example below in a file say myerr.4gl
-
compile myerr.4gl
4glpc --as-dll myerr.4gl
-
put the compiled myerr.so somewhere sensible
where it will be found because of LD_LIBRARY_PATH or ldconfig
-
export A4GL_ERRHOOK=myerr
Note: No need for .so or .dll suffix
There is a default implementation of the errlog() function in the standard Aubit4GL libraries.
14.9.1 A4GL_ERRHOOK
You can write your own shared library and set an environment variable A4GL_ERRHOOK to use your library implementation of errlog() instead of the default.
You don’t need to link anything with your application.
The function errlog() takes 4 parameters
-
Line Number: integer
-
Module Name: char(64)
-
Error Number: integer
-
Error Message: char(1024)
It does not return a value.
Mike Aubury has created an illustrative example in
lib/extra_libs/errhook in the aubit4gl source directory
You’ll find there a makefile, a README, and a 4gl module: sample.4gl
sample.4gl simply DISPLAYs all the information you could think of. but it would be easy to modify it to output via a report and send the result via email etc.
Heres an example output (We have wrapped some lines for this book):
********************************************
* ERRHOOK
********************************************
* User : aubit4gl
* Time : 2007-12-13 17:49:27
* Module : menuprog.4gl
* Line : 70
* Error : -3002
* PID : 11577
* lastkey : 2016
********************************************
* ScrDump : /tmp/scr.out.err_11577
********************************************
Customer Maintenance: Query Next Previous FireErr Add
Update Delete Exit
[ ]
Customer Number [ 2] Customer Name [ABC CHEMICALS PLC ]
Customer Address [Water Way. ]
[Runcorn ]
[Cheshire ]
[WA7 9LN ]
[ ]
Telephone Number [01925 849313 ]
Account Type [2 ]
Account Description [Credit: 60 days ]
6 Record(s) have been found
********************************************
* Errmsg :
* Program ./menuprog stopped at ’menuprog.4gl’,
line number 70.
* Error status number -3002.
* Wrong number of parameters passed to function.
*
* 4gl function call stack :
* menuprog.4gl (Line 8) calls MAIN
********************************************
To compile and use Mike’s sample.4gl:
cd lib/extra_libs/errhook
make
export CALLERRHOOK=errhook_sample
function errlog(ln,mod,err,errmsg)
define ln integer
define mod char(64)
define err integer
define errmsg char(1024)
define lv_cline char(2000)
define lv_continue integer
define a integer
define lv_fname_scrdump char(300)
define lv_l text
let lv_fname_scrdump="/tmp/scr.out.err_",
fgl_getpid() using "<<<<<<"
call aclfgl_dump_screen(lv_fname_scrdump)
locate lv_l in file lv_fname_scrdump
display "********************************************"
display "* ERRHOOK "
display "********************************************"
display "* User : ", aclfgl_get_user()
display "* Time : ", current year to second
display "* Module : ",mod clipped
display "* Line : ",ln
display "* Error : ",err
display "* PID : ",fgl_getpid()
display "* lastkey : ",fgl_lastkey()
display "********************************************"
display "* ScrDump : ",lv_fname_scrdump clipped
display "********************************************"
display lv_l
display "********************************************"
display "* Errmsg :"
# The error message contains embedded \n’s which mess up
# the display..
# here we’re just searching for them
# and using them as delimiters
let lv_continue=1
while lv_continue
let lv_continue=0
for a=1 to length(errmsg)
if ord(errmsg[a])=13 then
let errmsg[a]=’ ’
end if
if ord(errmsg[a])=10 then
if a>1 then
display "* ", errmsg[1,a-1]
else
display "*"
end if
let errmsg=errmsg[a+1,1024]
let lv_continue=1
exit for
end if
end for
end while
if length(errmsg) then
display "* ", errmsg clipped
end if
display "********************************************"
end function