by Richard Russell, February 2007
See also Structured Exception Handling and Cascaded ON CLOSE handling
There may be situations when you need to take some remedial action in the event of an error (for example to terminate a Windows API operation) but then to pass the responsibility for reporting the error to an existing error handler. You can do that using a combination of the ON ERROR LOCAL and RESTORE ERROR statements.
The short program below illustrates the principle. A deliberate error (here Division by zero) is generated in PROC2. This is handled locally within PROC2, in this example simply by printing a message to the screen. The error is then passed 'down the chain' to PROC1, which has its own opportunity to perform any special processing or clean-up operations; again this is illustrated by printing a message.
Finally PROC1 passes the error back down the chain to the catch-all ON ERROR statement in the main program:
ON ERROR PRINT "Error: " REPORT$ : END PROC1 END DEF PROC1 ON ERROR LOCAL RESTORE ERROR : PRINT "Error handled in PROC1" : ERROR ERR,REPORT$ PROC2 ENDPROC DEF PROC2 ON ERROR LOCAL RESTORE ERROR : PRINT "Error handled in PROC2" : ERROR ERR,REPORT$ A = 1/0 ENDPROC
Using this technique you can take local action in the event of an error, appropriate to the conditions at the time, but pass responsibility for further error processing/reporting to the routine that called the one in which the error occurred. Each procedure/function in the call chain can take some action in the event of an error, then pass it on.
If the procedure or function in which an error occurs has parameters and/or LOCAL or PRIVATE variables, the above code will not result in those variables being restored to the values they had when the PROC or FN was called. To achieve that, replace RESTORE ERROR with RESTORE LOCAL:
ON ERROR PRINT "Error: " REPORT$ : END PROC1(123) END DEF PROC1(par) LOCAL list_of_locals ON ERROR LOCAL RESTORE LOCAL : PRINT "Error handled in PROC1" : ERROR ERR,REPORT$ PROC2(-par) ENDPROC DEF PROC2(par) PRIVATE list_of_privates ON ERROR LOCAL RESTORE LOCAL : PRINT "Error handled in PROC2" : ERROR ERR,REPORT$ A = par/0 ENDPROC
Note that, if an error occurs, the location highlighted in the editor (or reported by means of a line number) will correspond to the most recent ON ERROR statement, not the place where the error originated. Some care may be be required in interpreting the results when debugging.