Hi.
Apparently I do not understand error handling like I thought I did.
Why is this error only caught if I have an ROUTINE-LEVEL ON ERROR UNDO, THROW statement in the code?
USING PROGRESS.Lang.*. RUN tryIt. PROCEDURE tryIt: RUN doIt. CATCH a AS AppError: MESSAGE a:ReturnValue VIEW-AS ALERT-BOX. END. END. PROCEDURE doIt: UNDO, THROW NEW AppError("Jeff's error!"). END PROCEDURE.
Yes - at first this is not intuitive. The error you are throwing inside doIt(), is raising error inside that procedure. Errors do not bubble out of blocks, ever, unless UNDO, THROW is in effect. So if you'd had a CATCH block inside doIt, it would have run.
With ROUTINE-LEVEL ON ERROR UNDO, THROW, it is saying that when error gets raised in doIt(), instead of just doing an UNDO, LEAVE, it will throw the error out of the block, up to the caller in this case. So then error gets raised again in the caller, at the RUN statement. So then your CATCH block will run.
Hi Jeff,
There's no default error handling properties on a procedure/function block that would cause the procedure to be able to CATCH the error. Since you added none in tryIt the application error was not passed back to the caller.
ROUTINE-LEVEL error handling is designed to impose implicit error handling at the sub-routine level for the following blocks (from the doc):
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
Note that BLOCK-LEVEL would also provide the desired behavior.
Ken Mc
Yeah... What Laura said.
Yes - at first this is not intuitive. The error you are throwing inside doIt(), is raising error inside that procedure. Errors do not bubble out of blocks, ever, unless UNDO, THROW is in effect. So if you'd had a CATCH block inside doIt, it would have run.
With ROUTINE-LEVEL ON ERROR UNDO, THROW, it is saying that when error gets raised in doIt(), instead of just doing an UNDO, LEAVE, it will throw the error out of the block, up to the caller in this case. So then error gets raised again in the caller, at the RUN statement. So then your CATCH block will run.
Hi Jeff,
There's no default error handling properties on a procedure/function block that would cause the procedure to be able to CATCH the error. Since you added none in tryIt the application error was not passed back to the caller.
ROUTINE-LEVEL error handling is designed to impose implicit error handling at the sub-routine level for the following blocks (from the doc):
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
Note that BLOCK-LEVEL would also provide the desired behavior.
Ken Mc
Yeah... What Laura said.
Thank you both. That helps jog the old noggin'.