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, THROW statement 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.