Cascaded+error+handling

//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:

code format="bb4w" 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 code

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**:

code format="bb4w" 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 code 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.