Defines an error-handling end block for any undoable ABL block. An end block is an ABL block that can occur only within another block. The block containing the end block is known as the associated block. End-blocks must occur between the last line of executable code in the associated block and the END statement.
block-statements
CATCH error-variable AS CLASS error-class:catch-logicEND CATCH .block-end-statementAll of the statements of an enclosing associated ABL block, except for its block-end-statement. The enclosing associated block can be any ABL block, including another CATCH block.The variable name that references the error object generated by the error condition. Typically, you do not define the error-variable ahead of time with the DEFINE VARIABLE statement. The AVM recognizes a new variable name on the CATCH statement as a new error-variable definition. Each CATCH in an associated block must have a unique error-variable. You can reuse an error-variable name in a different associated block, as long as its type is compatible with the new definition.error-classCLASSTypically Progress.Lang.SysError for system errors or Progress.Lang.AppError (or your subclass) for application errors. Optionally, you can provide the CLASS keyword.
associated-block:
...CATCH options :...END CATCH .FINALLY :...END FINALLY .END. /* associated-block */Note that a CATCH block can also contain a CATCH or FINALLY block, just as a FINALLY block can contain a CATCH or FINALLY block. For more information on FINALLY blocks, see the FINALLY statement reference entry.
ABL issues a compile-time error if a CATCH end block is present in a simple DO block, since simple DO blocks do not have error handling capabilities. DO blocks must have either TRANSACTION or an ON ERROR directive in order to have a CATCH. For example:
DO TRANSACTION. . .CATCH . . . :. . .END CATCH.END.
The code within a CATCH block is only executed if an ERROR of type error-class (or a sub-type) is raised within the body of the associated block. This behavior is also true if any sub-routine called by the associated block returns or raises an error of type error-class. When ERROR is raised, if there is an active transaction, the associated block is undone before the AVM begins executing the statements within the CATCH block.
If error is raised in a block and is not handled by a CATCH block, then the error is handled by the ON ERROR directive of the associated block. This could be an explicit ON ERROR phrase, or the implicit (default) ON ERROR directive for the block type.
A CATCH block can have a CATCH block within it. In this case, the contained CATCH block only handles errors raised within the CATCH block. To prevent infinite looping, any UNDO, THROW statement within the top-level CATCH block or any CATCH block nested within it immediately throws the error to the block that contains the associated block of the top-level CATCH block. For example:In this example, LEAVE the FOR EACH in the occurrence of a PrinterDown application error:
Note: For more information on infinite loop protection in error handling, see OpenEdge Getting Started: ABL Essentials.In the following code, if an Acme.Error.myAppError is caught the explicit UNDO, THROW statement causes the caught error to be thrown to the block enclosing the FOR EACH (remember that UNDO, THROW in a CATCH means leave associated block, then throw). However, if a Progress.Lang.SysError is caught the AVM will execute a NEXT on the FOR EACH block. For example:
© 2013 Progress Software Corporation and/or its subsidiaries or affiliates. |