I try to implement error handling with exceptions in 11.32
My problem is that it looks like the error continues to exist after it has been handled in the catch.
I run the code below in the procedure editor. I get an alertbox with the error. I did not expect that because I caught the error inte catch.
Also I get the alertbox 3 times!
Can anyone explain why?
ROUTINE-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE ttTest NO-UNDO
FIELD id AS CHARACTER
FIELD test-name AS CHARACTER
INDEX i-ttTest-1 IS PRIMARY UNIQUE id.
DO ON ERROR UNDO, LEAVE:
CREATE ttTest.
ASSIGN ttTest.id = "1"
ttTest.test-name = "2".
RELEASE ttTest.
CREATE ttTest.
ASSIGN ttTest.id = "1"
ttTest.test-name = "2".
RELEASE ttTest.
CATCH procerror AS Progress.Lang.ProError:
DISP "Inside catch".
END CATCH.
FINALLY:
DISP "Inside finally".
END FINALLY.
END.
Same result if I use BLOCK-LEVEL instead of Routine-LEVEL.
Flag this post as spam/abuse.
What happens if you use BLOCK-LEVEL instead of ROUTINE-LEVEL?
I'm no error handling guru, but IIRC with ROUTINE-LEVEL you still have to do an on-error throw on each block, whereas with BLOCK-LEVEL you don't.
Same result if I use BLOCK-LEVEL instead of Routine-LEVEL.
Same result if I use BLOCK-LEVEL instead of Routine-LEVEL.
Flag this post as spam/abuse.
Now it works. Thank you very much. :)
I think this is a combination of no-undo and buffer scoping.
NO-UNDO causes the error not to be undone. when the procedure ends the buffer goes out of scope and you get the error again.
ROUTINE-LEVEL ON ERROR UNDO, THROW. session:appl-alert = yes. session:system-alert = yes. session:debug-alert = yes. DEFINE TEMP-TABLE ttTest NO-UNDO FIELD id AS CHARACTER FIELD test-name AS CHARACTER INDEX i-ttTest-1 IS PRIMARY UNIQUE id. createblock: DO ON ERROR UNDO, LEAVE: CREATE ttTest. ASSIGN ttTest.id = "1" ttTest.test-name = "2". validate ttTest. CREATE ttTest. ASSIGN ttTest.id = "1" ttTest.test-name = "2". validate ttTest. CATCH procerror AS Progress.Lang.Error: message "Inside catch". if procerror:getmessagenum(1) = 132 then delete ttTest. leave createblock. END CATCH. FINALLY: message "Inside finally" error-status:error. END FINALLY. end. message "Done". CATCH procerror AS Progress.Lang.Error: message "Inside catch 2" procerror:getmessage(1). leave. END CATCH.
2nd cleaner solution with strong scoping
ROUTINE-LEVEL ON ERROR UNDO, THROW. session:appl-alert = yes. session:system-alert = yes. session:debug-alert = yes. DEFINE TEMP-TABLE ttTest NO-UNDO FIELD id AS CHARACTER FIELD test-name AS CHARACTER INDEX i-ttTest-1 IS PRIMARY UNIQUE id. createblock: DO ON ERROR UNDO, LEAVE: do for ttTest: /* strong scope */ CREATE ttTest. ASSIGN ttTest.id = "1" ttTest.test-name = "2". CREATE ttTest. ASSIGN ttTest.id = "1" ttTest.test-name = "2". end. CATCH procerror AS Progress.Lang.Error: message "Inside catch" procerror:getmessage(1). END CATCH. FINALLY: message "Inside finally" error-status:error. END FINALLY. end. message "Done". CATCH procerror AS Progress.Lang.Error: message "Inside catch 2" procerror:getmessage(1). leave. END CATCH.
Thanks for the answer. I will look into this solution also.
Just to clarify, there was no transaction so temp-tables changes are not undone in that case (that is documented). So whether it was an undo or no-undo temp-table, when there is no transaction active, the changes will not be undone. The record remains in scope and the errors will come up as we try to release the record when ending the procedure.