The BLOCK-LEVEL ON ERROR UNDO, THROW statement changes the default implicit ON ERROR phrase to ON ERROR UNDO, THROW for every supported block type in the file that contains the statement. This is specifically for ERROR, not STOP conditions because STOP conditions are already thrown by default. The following blocks are affected by this statement:

  • Procedure (also called main block, external procedure, or .p file, including database trigger .p files)
  • Internal procedure
  • Database trigger (ON block with CREATE, DELETE, WRITE, or ASSIGN event)
  • User-defined function
  • Constructor
  • User-defined method
  • User-defined property getter/setter
  • REPEAT
  • FOR
  • DO TRANSACTION

The following blocks are not affected:

  • Any block for which an error-handling directive is explicitly specified
  • Simple DO block
  • DO WHILE block
  • Destructor
  • UI trigger

Syntax

BLOCK-LEVEL ON ERROR UNDO, THROW.

The following rules affect the placement of the BLOCK-LEVEL ON ERROR UNDO, THROW statement:

  • The statement occurs once in each source file in which the behavior is desired.
  • The statement must come before any definitional or executable statement in the procedure or class file.
  • The statement can come before or after a USING statement.

Example

To create an application that uses structured error handling to handle all uncaught local errors at the top level:

  1. Include the BLOCK-LEVEL ON ERROR UNDO, THROW statement in all your procedure and class files.
  2. For each basic block, decide whether a different explicit flow of control directive is appropriate.
  3. Add a CATCH block for the Progress.Lang.Error interface to your startup procedure block. For more information, see CATCH Blocks.
  4. Add a CATCH block locally for any errors you want to handle at a local level.

The following simple example illustrates the design pattern:

BLOCK-LEVEL ON ERROR UNDO, THROW. 

PROCEDURE find1000:
    /* Ignore potential errors */
    FIND FIRST Customer WHERE CustNum = 1000 NO-ERROR. 
END PROCEDURE.

PROCEDURE find2000:
    FIND FIRST Customer WHERE CustNum = 2000.

    CATCH eSysError AS Progress.Lang.SysError:
        /* Take care of this error locally */ 
    END CATCH.
END PROCEDURE.

PROCEDURE find3000:
    FIND FIRST Customer WHERE CustNum = 3000.
END PROCEDURE.

/* Main Startup Procedure Block */ 

RUN find1000.
RUN find2000. 
RUN find3000.

/* Won't execute because error will be raised here by find3000 */
MESSAGE "Application completed execution successfully." 
    VIEW-AS ALERT-BOX BUTTONS OK.

CATCH eAnyError AS Progress.Lang.Error:
    MESSAGE "Unexpected error occurred..." SKIP 
            "Logging information..." SKIP 
            "Exiting application..."
                VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.