In the code below, the doIt() always returns the unknown(?) value.
In the CATCH block I can see there is a value for c that has been fetched from e:getMessage(1).
I can make this work by putting my FIND and CATCH in its own DO block but I was just curious why it behaves the way it does. What nuance am I misunderstanding?
USING PROGRESS.lang.*. FUNCTION doIt RETURNS CHARACTER(): DEFINE VARIABLE c AS CHARACTER NO-UNDO. FIND Customer NO-LOCK WHERE Customer.Name = "xxx". RETURN c. CATCH e AS SysError: c = e:GetMessage(1). MESSAGE c VIEW-AS ALERT-BOX INFORMATION BUTTONS OK. END CATCH. END FUNCTION. MESSAGE doIt() VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
I did notice that behavior in the debugger but thought maybe it was a debugger quirk. I incorrectly assumed that the RETURN would always get executed.
Third attempt at replying..
Thanks. I did notice that behavior in the debugger but thought it was a quirk. I incorrectly assumed that the RETURN statement would always get executed.
If you wrap it in a
it will probably be executed after the catch.
It seems odd to put it in a FINALLY block. I think I'll keep my inner DO. :)
YEAH. You did the right thing! The FINALLY block was not meant to add code that would override behavior in the main block. We should never even have allowed RETURN statements in FINALLY blocks. So your feeling that it seemed odd means you have good instincts :-)
Why would you not have allowed RETURN statement?
For the reason I said - the FINALLY block is meant to do clean-up code and the like. It is not meant to override the behavior of the main block.
The really obnoxious case is when there is no error condition and the main code does RETURN 10 and the FINALLY block does RETURN 20. We allow that! What the heck does that mean? The ABL will return 20 (the last statement wins).
Another case, which is a variation of the one in this post is that there is an untrapped error in the main block (i.e., it is not caught). And then the FINALLY statement does RETURN 10. Well, if you wanted to ignore the error, why didn't you catch it or use NO-ERROR? Just returning a good value from the FINALLY when an error happened that you didn't handle is a very bad coding practice.
In C#, for example, they do not allow return statements in finally blocks to avoid all of this confusion.
I've never used a return statement in a finally block. I'm having trouble coming up with a valid use-case. Just out of curiosity I checked 1500 random finally statements from our code base. Not a single one of them uses return :-)
So that makes you even more right ;-)
Hi Peter. Great example. Indeed not something you would do often...
and if you do use it occasionally, you might get into trouble when Laura decides to pull the plug on the feature :-)
I think the plug should be unppluged asap, before code begins to stack in the millions of cases..