Try OpenEdge Now
skip to main content
Error Handling
Handling Errors with CATCH Blocks : UNDO scope and relationship to a CATCH block
 

UNDO scope and relationship to a CATCH block

The CATCH block is an end block of its associated block. The CATCH block only executes when error is raised in the associated block and the error type specified in the CATCH statement is compatible with the type of the raised error. At the point the CATCH block executes, several steps in the error handling process are already complete, and this state affects what data is available to your CATCH block:
*Any transaction within the associated block will already be undone. In other words, changes made within the associated block to persistent data, undo variables, and undo temp-table fields have already been discarded.
*Records scoped to the associated block will be released before the CATCH block executes. (See Bufferscope within a CATCH block, for more information on buffer scope.)
*Even if no transaction is present, undoable variables and temp-table fields changed by the associated block will be restored to their last valid values before the associated block began its execution. Remember that a variable or temp-table field is undoable by default. (The NO-UNDO option on the DEFINE statement changes this default.)
The following example with step by step comments demonstrates these availability rules:
/* Defines an undoable variable because the NO-UNDO option is not specified. */
DEFINE VARIABLE TargetCustNum AS INTEGER.

/* The last valid value before the beginning of the DO block */
ASSIGN TargetCustNum = 1.

DO ON ERROR UNDO, LEAVE:

/* This value will be undone on ERROR! */
ASSIGN TargetCustNum = 15.

/* Find a Customer */
FIND Customer WHERE Customer.CustNum = TargetCustNum.

/* Change the database! A transaction is now active. */
ASSIGN Customer.Name = Customer.NAME + " And Much More".

/* Confirm change to persistent field. */
MESSAGE "Customer Name changed to: " Customer.Name
        VIEW-AS ALERT-BOX BUTTONS OK.

/* ERROR raised. Control passes to CATCH block. */
FIND Order OF Customer WHERE OrderNum = 1234.

/* Statement will not execute. */
DISPLAY Customer.CustNum SKIP
            Customer.Name SKIP
            OrderNum SKIP
OrderStatus
                VIEW-AS TEXT WITH FRAME b SIDE-LABELS.

CATCH eSysError AS Progress.Lang.SysError:

/* Confirm if Customer record is available in CATCH. */
IF AVAILABLE (Customer) THEN
MESSAGE "Customer record is still available."
                VIEW-AS ALERT-BOX BUTTONS OK.
ELSE DO:
MESSAGE "No Customer record is currently available."
VIEW-AS ALERT-BOX BUTTONS OK.

/* Re-Find the Customer. Cannot rely on value of TargetCustNum! */
FIND Customer WHERE Customer.CustNum = 15.

/* Confirm that change to database field was not committed
and UNDO variable was rolled back. */
MESSAGE "TargetCustNum = " TargetCustNum SKIP
"Customer name is now: " Customer.Name
                        VIEW-AS ALERT-BOX BUTTONS OK.
END. /* ELSE */

     END CATCH.
END. /* DO */