Consultor Eletrônico



Kbase P164717: 4GL/ABL: RETURN statement in a FINALLY block of a function suppresses previously thrown error
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   5/4/2010
Status: Unverified

SYMPTOM(s):

4GL/ABL: RETURN statement in a FINALLY block of a function suppresses previously thrown error

If the FINALLY block in the following snippet is un-commented, the MESSAGE statement does not display the previously thrown error:

ROUTINE-LEVEL ON ERROR UNDO , THROW.
FUNCTION test RETURNS LOGICAL() FORWARD.
test().
CATCH e AS Progress.Lang.Error :
MESSAGE e:GetMessage(1) VIEW-AS ALERT-BOX.
END CATCH.
FUNCTION test RETURNS LOGICAL():
IF TRUE THEN
UNDO, THROW NEW Progress.Lang.AppError("This is my error message. (550)", 550).
FINALLY:
/* RETURN TRUE. */
END FINALLY.
END FUNCTION.

FACT(s) (Environment):

All Supported Operating Systems
OpenEdge 10.1C
OpenEdge 10.2A
OpenEdge 10.2B

CAUSE:

This is expected behavior. RETURN directs flow of control. Using RETURN changes the flow of control that would have occurred without it, which means the THROW that had previously been in force does not occur. The same thing would happen if a THROW in the FINALLY throws a different error. In that case, the MESSAGE would display the error from the FINALLY, not from the previous THROW. So by using the RETURN or a THROW, in the FINALLY block changes the directive.

FIX:

This is expected behavior and is somewhat documented in the FINALLY end block section of the error handling book: "The code in any FINALLY block can contain explicit flow-of-control options: LEAVE, NEXT, RETRY, RETURN, or THROW. Since FINALLY is an undoable block, LEAVE, NEXT, and RETRY without a label apply to the FINALLY block itself and not to the associated block."
What is not stated in the documentation is that RETURN and THROW can only apply to the associated block. The documentation also does not state that RETURN and THROW change the flow of control that would have occurred if you had not included a specific flow of control option in your FINALLY block. A documentation bug has been submitted to make the RETURN and THROW behavior clearer in this context.