ONERROR
Enable trapping of runtime errors
WSupported on Windows
|
USupported on Unix
|
VSupported on OpenVMS
|
NSupported in Synergy .NET
|
ONERROR label
or
ONERROR(error_list) label[, (...)...][, catch_all]
Arguments
label
In the unqualified form, a single statement label to which control is immediately transferred if a trappable runtime error occurs. In the qualified form, label is one or more statement labels to which control is transferred if any error in the associated list occurs.
error_list
A list of errors separated by commas that cause execution to be transferred to the associated label. Each list is made up of one or more compile-time expressions, which can be error numbers, error literals, or literal variables, as long as the expression can be evaluated to a number by the compiler. (n)
catch_all
(optional) A statement label to which control is transferred if an error that is not one of the listed errors occurs.
Discussion
The ONERROR statement sets one or more error traps to detect and handle runtime errors. The unqualified form of the statement specifies a single label. The qualified form of the ONERROR statement sets several error traps, each defined by a list of error numbers being trapped and the label to which control is transferred.
When an ONERROR statement is executed, all error traps created by any previously executed ONERROR statements are canceled. Only those traps created by the current ONERROR statement are defined. The defined error traps remain in effect until one of the following conditions occurs:
- An OFFERROR statement is executed.
- A new ONERROR statement is executed, causing the current traps to be canceled and new traps to be set.
- In traditional Synergy, an external subroutine or user-defined function is called, which suspends the current error traps until the subroutine or function returns. Upon returning, the error traps are re-established.
- The program terminates.
ONERROR statements incur a performance penalty in Synergy .NET. We highly recommend that you use I/O error lists instead of ONERROR or TRY-CATCH.
In Synergy .NET, ONERROR only traps Synergy mappable errors for exceptions thrown from the current or any called routine that are (or derive from) Synergex.SynergyDE.SynException or the following system exceptions:
- InvalidOperationException ($ERR_INVOPER)
- InvalidCastException ($ERR_INVCAST)
- OutOfMemoryException ($ERR_NOMEM)
- OverflowException ($ERR_BIGNUM)
- DivideByZeroException ($ERR_DIVIDE)
- IndexOutOfRangeException ($ERR_ARRAYBNDS)
- ArgumentNullException ($ERR_NULARG)
- FormatException ($ERR_DIGIT)
- ArgumentOutOfRangeException ($ERR_OUTRNG)
If an ONERROR loop occurs during I/O to a server, aborting the runtime with Ctrl+C or one of the Windows functions may take a long time, making the abort appear not to work. |
If none of the following exist, a fatal traceback is generated by the runtime:
- ONERROR statement
- error list for an individual statement
- TRY-CATCH block (in the current or a prior routine)
However, if you are using a product (such as xfServerPlus) that must be able to control all exceptions so it can provide information to the caller, you’ll want to include the $ERR_CATCH literal in your error list or TRY-CATCH to enable catch functionality. Error catching enables a routine to set an ONERROR trap that is called whenever an untrapped error occurs in a routine lower in the call tree.
In traditional Synergy, $ERR_CATCH cannot catch an untrapped error that is thrown in a callback routine. |
When using $ERR_CATCH, the routine must use the %ERR_TRACEBACK function to retrieve (or clear, if not required) the error traceback information that would have been reported had the error not been trapped. If %ERR_TRACEBACK is not used, additional caught errors continue appending information to the internal catch buffers until memory is exhausted. See the second example in Examples below.
See also
- Record locking
- %ERR_TRACEBACK routine
In this example, the OFFERROR statement ensures that the error traps are canceled at the bad and what labels. If an error occurs, the program terminates.
.define TTCHN ,1 record alpha ,a10 decml ,d5 errmsg ,a40 proc open(TTCHN, i, "tt:") repeat begin display(TTCHN, "Enter number (1-7 digits): ") reads(TTCHN, alpha) [eof=done] onerror ($ERR_DIGIT) bad, what decml = alpha offerror writes(TTCHN, "... It was valid") nextloop bad, offerror writes(TTCHN, "... It was not valid") nextloop what, offerror errmsg = %ernum, "Error XXX: " xcall ertxt(%ernum, errmsg(12,40)) writes(TTCHN, errmsg) end done, stop end
The following example illustrates using the $ERR_CATCH mnemonic to enable the catching of errors in called routines that do not have an ONERROR statement.
main .align record tty ,i4 sts ,i4 record error_description ,a255 proc onerror ($ERR_CATCH) caught xcall routine_to_call stop caught, offerror open(tty=0, o, 'tt:') writes(tty,"error "+%string(%ernum)+" was caught") while (%err_traceback(error_description)) writes(tty, %atrim(error_description)) stop end subroutine routine_to_call proc xcall cause_an_error xreturn endsubroutine subroutine cause_an_error record d ,i2 zero ,i2 proc d = d/zero xreturn endsubroutine