The most efficient way to detect errors from commands is by creating condition traps, using the SIGNAL ON and CALL ON instructions, with either the ERROR or the FAILURE condition. When used in a program, these instructions enable, or switch on, a detector in Rexx that tests the result of every command. Then, if a command signals an error, Rexx stops usual program processing, searches the program for the appropriate label (ERROR:, or FAILURE:, or a label that you created), and resumes processing there.
SIGNAL ON and CALL ON also tell Rexx to store the line number (in the Rexx program) of the command instruction that triggered the condition. Rexx assigns that line number to the special variable SIGL. Your program can get more information about what caused the command error through the built-in function CONDITION.
Using the SIGNAL and CALL instructions to handle errors has several advantages; namely, that programs:
Are easier to read because you can confine error-trapping to a single, common routine
Are more flexible because they can respond to errors by clause (SIGL), by return code (RC), or by other information (CONDITION method or built-in function)
Can catch problems and react to them before the environment issues an error message
Are easier to correct because you can turn the traps on and off (SIGNAL OFF and CALL OFF)
For other conditions that can be detected using SIGNAL ON and CALL ON, see the Open Object Rexx: Reference.
The instructions to set a trap for errors are SIGNAL and CALL. Example formats are:
SIGNAL ON condition NAME trapname CALL ON condition NAME trapname
The SIGNAL ON instruction initiates an exit subroutine that ends the program. The CALL ON instruction initiates a subroutine that returns processing to the clause immediately following the CALL ON instruction. You use CALL ON to recover from a command error or failure.
The command conditions that can be trapped are:
Detects any nonzero error code the default environment issues as the result of a Rexx command.
Detects a severe error, preventing the system from processing the command.
A failure, in this sense, is a particular category of error. If you use SIGNAL ON or CALL ON to set a trap only for ERROR conditions, then it traps failures as well as other errors. If you also specify a FAILURE condition, then the ERROR trap ignores failures.
With both the SIGNAL and the CALL instructions, you can specify the name of the trap routine. Add a NAME keyword followed by the name of the subroutine. If you do not specify the name of the trap routine, Rexx uses the value of condition as the name (Rexx looks for the label ERROR:, FAILURE:, and so on).
For more information about other conditions that can be trapped, see the Open Object Rexx: Reference.
To turn off a trap for any part of a program, use the SIGNAL or CALL instructions with the OFF keyword, such as:
SIGNAL OFF ERROR SIGNAL OFF FAILURE CALL OFF ERROR CALL OFF FAILURE
The following example shows how a program can use SIGNAL ON to trap a command error in a program that copies a file. In this example, an error occurs because the name of a nonexistent file is stored in the variable file1. Processing jumps to the clause following the label ERROR:
If there were a way to recover, such as by typing another file name, you could use CALL ON to recover and resume processing:
The following example shows a simple error trap that you can use in many programs:
/* Here is a sample "main program" with an error */ signal on error /* enable error handling */ "ersae myfiles.*" /* mistyped "erase" instruction */ exit /* And here is a fairly generic error handler for this */ /* program (and many others...) */ error: say "error" rc "in system call." say say "line number =" sigl say "instruction = " sourceline(sigl) exit