CATCH blocks within CATCH blocks

A CATCH block within a 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 ON ERROR UNDO, LEAVE:
        < 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 */ 
    END CATCH.

END. /* FOR EACH */

In this example, notice the UNDO, THROW statement within the nested CATCH block. If we get here, the AVM passes control to the block enclosing the associated block and raises ERROR there. In 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.