Introduction to CATCH blocks
- Last Updated: May 24, 2019
- 2 minute read
- OpenEdge
- Version 13.0
- Documentation
A CATCH block can be referred to as an end block because it defines end-of-block processing for the
block that encloses it. End blocks are always part of another block called the associated block. End blocks must appear in the associated
block after the last executable statement and before the END statement. The other type of end block is the FINALLY block that is discussed in later topics.
The CATCH statement defines the start of an end
block that only executes if a condition is raised in its associated block, and the type
of condition raised is the type specified in the CATCH
statement (or a subtype of that type). For example:
|
In this example:
- The
THROWdirective tells the AVM to propagate any unhandled errors to the procedure (main) block, since it is the enclosing block of theDO TRANSACTIONblock. Notice there is aCATCHblock waiting to handle anyProgress.Lang.AppErrorobject that may be raised from theRUNstatement. If aProgress.Lang.AppErrorobject is raised, theCATCHblock handles the error and it is not passed to the procedure block. - When running the code, if the
FINDstatement fails, and there is no error handler present for this error type, it raises aProgress.Lang.SysError. SinceProgress.Lang.SysErroris not handled, the AVM throws the error up the call stack to the procedure block, due to theUNDO, THROWdirective of theTRANSACTIONblock. The AVM finds a compatibleCATCHblock on the procedure block and then executes the code in theCATCHblock. - If you delete the
CATCHblock on the procedure block and run the example code, the AVM propagates theProgress.Lang.SysErrorobject to the main block as before. Since you no longer have an appropriate error handler in the main block, the AVM now executes the default error handling behavior, which is to display the system error message to the default output device.
The CATCH block executes once for each iteration of its associated block
that raises a compatible error. A block can have multiple CATCH blocks,
and all must come at the end of the associated block.
There can only be one CATCH block for each
specific condition type in a block. A CATCH block also
handles objects for its subtypes, so it is possible there can be more than one CATCH block that is compatible with a particular condition.
In this case, the AVM executes the first CATCH block it
encounters that is compatible. For this reason, CATCH
blocks should be arranged from the most specific type to the most general. For example,
if you had different error handling code for Progress.Lang.SysError objects and Progress.Lang.SoapFaultError objects, put the CATCH block for SoapFaultError objects
first. Otherwise, since SoapFaultError objects are a
subtype of SysError, a CATCH block for SysError that appears
first would handle the SoapFaultError object.