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:

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:

Note

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.

Error catching

If none of the following exist, a fatal traceback is generated by the runtime:

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.

Note

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.

Examples

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