Try OpenEdge Now
skip to main content
ABL Reference
ABL Syntax Reference : ROUTINE-LEVEL ON ERROR UNDO, THROW statement
 

ROUTINE-LEVEL ON ERROR UNDO, THROW statement

Use this statement in a procedure (.p) or class (.cls) file to change the implicit, default ON ERROR directive from UNDO, RETRY to UNDO, THROW for all routine-level blocks in a file. The statement must come before any executable or DEFINE statements in a file. However, it can come either before or after a USING statement.

Syntax

ROUTINE-LEVEL ON ERROR UNDO, THROW.
The following blocks are the routine-level blocks affected by this statement:
*Main block of an external procedure (.p)
*Internal procedures
*User-defined functions
*Methods of a class
*Class constructors
*Property accessors
*ON blocks used as database triggers with CREATE, DELETE, WRITE or ASSIGN events
This statement does not affect:
*Destructors
*DO, FOR, or REPEAT blocks contained within the routine-level blocks
*ON blocks that are UI triggers.
Note these alternatives to the ROUTINE-LEVEL ON ERROR UNDO, THROW statement:
*Instead of adding the statement to source-code files, you can use the -undothrow 1 startup parameter to change the default error-handling on routine-level blocks to UNDO, THROW during compilation. See the OpenEdge Deployment: Startup Command and Parameter Reference for more information.
*The BLOCK-LEVEL ON ERROR UNDO, THROWstatement can be used if you want to change the default error-handling on REPEAT, FOR, and DO TRANSACTION blocks in addition to routine-level blocks. (You can use the -undothrow 2 startup parameter to change the default error-handling to UNDO, THROW on every block affected by the BLOCK-LEVEL statement during compilation.)

Example

This code propagates an error from an internal procedures up to the main procedure block.
r-ROUTINE-LEVEL-01.p
ROUTINE-LEVEL ON ERROR UNDO, THROW.

PROCEDURE find1000:
  FIND FIRST Customer WHERE Customer.CustNum = 1000.
END PROCEDURE.

PROCEDURE find2000:
  FIND FIRST Customer WHERE Customer.CustNum = 2000.
END PROCEDURE.

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

/* Main Block */
RUN find1000.
RUN find2000.
RUN find3000.

CATCH eAnyError AS Progress.Lang.SysError:
  MESSAGE "Your CATCH block associated with the the main block (.p) has handled an error in an internal procedure."
    VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.

Notes

*The ROUTINE-LEVEL ON ERROR UNDO, THROW statement guarantees that all unhandled errors in a sub-procedure of a persistent procedure or method of a class will be propagated up to the caller. You decide for each sub-procedure or method within the file whether that sub-procedure or method should handle errors with its own CATCH block. Alternatively, you may want a CATCH block at the caller level to handle errors. This can be useful if a caller calls many internal procedures in a persistent procedure or many methods in a class.
*Routine-level blocks have an implicit, default ON ERROR UNDO, RETRY phrase (with infinite loop protection). You cannot change the default behavior for individual routine-level blocks to throw or re-throw errors by adding an ON ERROR phrase in the code.
*When a routine-level block or a database trigger has a CATCH statement associated with it that explicitly handles the thrown error, then the CATCH block handles the error. The error is not thrown up the call stack , unless the CATCH block rethrows it.
*Error objects can be thrown from an AppServer and handled by a CATCH block on an ABL client. To be throwable from an AppServer to an ABL client, user-defined error classes must be defined on both the server and client sides, and the classes must be defined as SERIALIZABLE. For the full list of restrictions on class-based objects that are passed between AppServer and client, see the Parameter passing syntax entry. For more information on error handling in general, see OpenEdge Development: Error Handling.

See also

BLOCK-LEVEL ON ERROR UNDO, THROWstatement, ON ENDKEY phrase, ON ERROR phrase, ON QUIT phrase, RETURN statement, RETURN-VALUE function, STOP statement, UNDO-THROW-SCOPE attribute