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. This is
specifically for ERROR, not STOP conditions because STOP conditions are
already thrown by default. The statement must come before any executable or DEFINE statements in a file. However, it can come either before
or after a USING statement. In a .cls
file, the statement must come before the CLASS 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 subprocedure of a persistent
procedure, or method of a class, are propagated up to the caller. You decide for each
subprocedure, or method within the file, whether that subprocedure 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.
- You cannot change the default behavior for individual routine-level
blocks to throw or rethrow errors.
- 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: ABL Error Handling.