Try OpenEdge Now
skip to main content
Error Handling
Handling Errors with CATCH Blocks : CATCH blocks within CATCH blocks

CATCH blocks within CATCH blocks

The CATCH block is an undoable block with implicit ON ERROR UNDO, THROW error handling. You cannot explicitly override the ON ERROR directive for a CATCH block. If a statement within the CATCH block raises ERROR and there is no nested CATCH block, the CATCH block will be undone, and the ERROR will be raised in the block that encloses the associated block of the CATCH. So a statement that raises ERROR within a CATCH block causes the following to occur:
1. UNDO the CATCH block.
2. Leave the CATCH and its associated block.
3. THROW the error to the enclosing block. If the CATCH block is at the routine level, then the error gets thrown to the caller of the routine. The same behavior occurs for an explicit UNDO, THROW statement in a CATCH block.
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 encloses the associated block of the top-level CATCH block. For example:
FOR EACH Customer:
    /* FOR EACH code body */

        /* DO code body */

        CATCH eAppError AS Progress.Lang.AppError:
            /* CATCH code body */

            CATCH eSysError AS Progress.Lang.SysError:
                UNDO, THROW eSysError. /* Will be handled by CATCH
                                          anyError on FOR EACH... */
            END CATCH.
        END CATCH.
    END. /* DO */

    CATCH anyError AS Progress.Lang.Error:
        /* Handler code for anyError condition */

In this example, notice the UNDO, THROW statement within the nested CATCH block in the DO block. The top-level CATCH block associated with the DO block handles application errors. The nested CATCH block handles any system errors that occur in the top-level CATCH block. If ERROR is raised, then the UNDO, THROW statement in the nested CATCH block immediately passes control to the block enclosing the associated block of the top-most CATCH block in a set of nested CATCH blocks. If this case, the DO block is the associated block and the FOR EACH is the block enclosing the DO block. The CATCH anyError block on the FOR EACH block then handles the error.
If there is a FINALLY block in the associated block, the FINALLY code will be executed before ERROR gets raised in the block enclosing the associated block.