Error and Exception Handling
Contents
Error and Exception Handling
When an error occurs in a running application, Recital will stop execution, display an error message and create an error.mem file, unless an alternative error handling procedure has been specified.
The error.mem file
The error.mem file includes the following information:
- The Recital Product version, release, platform and compile date information
- System information, such as maximum file size and maximum process stack
- Recital License information
- User and Node names and process ID
- The error number
- The error message
- The program line
- The program line number
- A stack trace of the programs and procedures called
- A list of all active public and private memory variables and classes
- Status of open tables, indexes and current records.
- Settings listing as per LIST STATUS
SET ERRORVERSION
The error.mem file will be named error.mem and will be overwritten by subsequent errors unless set errorversion is on. If set errorversion is on, multiple numbered error.mem files are created with the following naming format:
error0001.mem, error0002.mem, error0003.mem, ...
DB_ERRORDIR
The error.mem file(s) will be created in the directory that is current when the error occurs unless the DB_ERRORDIR environment variable is set. If set, DB_ERRORDIR points to a directory in which the error.mem file(s) will be created.
The ON ERROR statement
Alternative error handling procedures can be specified using the on error command. When there is an active on error setting, no error.mem file will be created and program execution willl not be halted. It is now up to the on error error handler to trap the information required in order to trace the error and to take appropriate action based on the error that has occurred.
on error [command]
SET ONERROR
The active on error behavior can be toggled on and off using the set onerror command.
set onerror on | off
Error Information Functions
Several functions are available to give information about errors:
- errno() - returns last operating system error number
numeric = errno()
- strerror() - returns last or specified operating system error description
character = strerror([error as numeric])
- error() - returns Recital error number
numeric = error()
- message() - returns Recital error message
character = message()
- message(1) - returns the line of code which caused the error
character = message(1)
- procline() - returns currently executing procedure line number
numeric = procline()
- procname() - returns currently executing procedure name
character = procname()
It is important to note that the procline() and procname() functions return information about the currently executing procedure. If these functions are called from within the error handling procedure, they will give information based on the error handling procedure itself and not the procedure in which the error occurred. They should, therefore, be specified as parameters to the error handler, e.g.
on error do MyErrProc with procname(), procline()
RETRY
The RETRY command can be used in conjunction with an on error error handler. It re-executes the command that was reported as being in error.
procedure checkexclu // Check for file is in use error if error() = 15 nResponse = messagebox("File currently in use",5) if nResponse = 4 sleep 1 retry else cancel endif else messagebox("Exiting") cancel endif return on error do checkexclu open database southwind shared use example exclusive on error
SAVE ERROR
The save error command allows for the creation of an equivalent of the error.mem file. It is given a '.mem' file extension.
procedure handle308 if error() = 308 // Access to PRIVATE member of object denied // Expected behavior: carry on return else messagebox("Unhandled error has occurred - exiting") save error to errlog cancel endif endproc class myclass protected prop1 = "Protected property" public procedure mymethod() echo prop1 + "\n" endproc endclass myobject = new myclass() // Throws error 308 as prop1 is protected and can only be accessed by methods inside the class or sub-class on error handle308() echo myobject.prop1 // This will work as class method can access protected property myobject.mymethod() // Throws error 292 as prop2 does not exist echo myobject.prop2 on error