Hey there. When I run the following code (replace dbxExample and ttxExample with one of your tables) and UNDO, THROW NEW statement is run in PROCEDURE AfterExampleRowFill, the statement does not exit the entire FILL and go to the procedure level CATCH. That what I expect. If not how would I do that?
ROUTINE-LEVEL ON ERROR UNDO, THROW.
DEFINE TEMP-TABLE ttxExample NO-UNDO LIKE dbxExample.
DEFINE DATASET pdxExample FOR ttxExample.
DEFINE QUERY quxExample FOR dbxExample.
QUERY quxExample:FORWARD-ONLY = TRUE.
DEFINE DATA-SOURCE dsxExample FOR QUERY quxExample.
DATA-SOURCE dsxExample:MERGE-BY-FIELD = FALSE.
BUFFER ttxExample:ATTACH-DATA-SOURCE(DATA-SOURCE dsxExample:HANDLE).
DO ON ERROR UNDO, THROW:
QUERY quxExample:QUERY-PREPARE("FOR EACH dbxExample WHERE TRUE").
BUFFER ttxExample:SET-CALLBACK-PROCEDURE ("AFTER-ROW-FILL", "AfterExampleRowFill").
BUFFER ttxExample:FILL-MODE = "empty".
BUFFER ttxExample:FILL().
CATCH eSysError AS Progress.Lang.SysError:
MESSAGE "inside FILL SysError CATCH " eSysError:GetMessageNum(1) eSysError:GetMessage(1).
DELETE OBJECT eSysError.
END CATCH.
CATCH eAppError AS Progress.Lang.AppError:
MESSAGE "inside FILL CATCH " eAppError:GetMessageNum(1) eAppError:GetMessage(1).
DELETE OBJECT eAppError.
END CATCH.
FINALLY:
END FINALLY.
END.
CATCH eSysError AS Progress.Lang.SysError:
MESSAGE "PROCEDURE SysError CATCH " eSysError:GetMessageNum(1) eSysError:GetMessage(1).
DELETE OBJECT eSysError.
END CATCH.
CATCH eAppError AS Progress.Lang.AppError:
MESSAGE "PROCEDURE AppError CATCH " eAppError:GetMessageNum(1) eAppError:GetMessage(1).
DELETE OBJECT eAppError.
END CATCH.
CATCH eError AS Progress.Lang.Error:
DELETE OBJECT eError.
END CATCH.
FINALLY:
END FINALLY.
PROCEDURE AfterExampleRowFill PRIVATE:
DEFINE INPUT PARAMETER DATASET FOR pdxExample.
UNDO, THROW NEW Progress.Lang.AppError("my row fill app error", 123).
CATCH eAppError AS Progress.Lang.AppError:
IF eAppError:GetMessageNum(1) = 123 THEN do:
message "in AfterExampleRowFill about to THROW error".
UNDO, THROW eAppError.
end.
ELSE DO:
MESSAGE "inside PROCEDURE EVENT CATCH " eAppError:GetMessageNum(1) eAppError:GetMessage(1).
DELETE OBJECT eAppError.
END.
END CATCH.
FINALLY:
END FINALLY.
END.
The usual way to end a FILL is to RETURN ERROR. If PSC didn't couple UNDO, THROW with that behavor, then I guess you're out of luck.
Try contact PSC TS on this one.
well, first I though that someone just wanted to confuse the compiler with all those catch blocks for only a hand full of useful lines of code
return error from fill events did not make the error persist, the fill just stops although there might have been already a number of records loaded in that fill... error status is not set to error and code execution continues.
this is just another case that shows that the mixed error handling is still flawed and probably need to be rethink... for some strange reason the AppError which is thrown from the fill event call-back is not trapped by any catch block, in fact it's simply 'thrown' on the screen during the fill event. The fill stops as if return error have been used and execution continues afterward, just that the standard error message is shown and this can't be inhibited not even by adding no-error to the buffer fill call
what is even more confusing is that if another constructor of AppError is used the message is not being shown and we get the same behaviour as when using return error - undo throw new AppError() or AppError('message').
bottom line, in a fill event call-back method just stick to return error and don't bother to use throw as you're not going to be able to catch it and I think that given the current implementation the 'bug' is that you get the default error message when you use the two parameters constructor... in fact the error shouldn't be shown, just that the fill stops loading more records.
Yes thanks. I realize part of my original question was wrong and the new error thrown does stop the entire fill. Anyways yes I guess I will have to use some traditional error processing and check the error-status system handle. Unfortunately I can't rely on structured error processing for this.
TS mentioned can also check the ProDataSet ERROR attribute.
true but, did they by any chance gave you an answer as why only when the two parameters constructor of AppError is used the error is not trapped by the internal fill implementation and end up being displayed as a message on the screen?
Yeah. TS said it would be a great enhancement to the product and suggested I log an enhancement request.
Yes it seems this should already be in the product but there is the statement in OpenEdge Development: ProDataSets manual explicitly states in the chapter entitled ProDataSets Events:
“
If a callback procedure attempts to raise error for a FILL event, either through the traditional RETURN ERROR or through the structured UNDO, THROW, the ProDataSet ERROR attribute is set to
true. Error is not raised to the caller.
”
Mind you the above isn't very exact to my situation.
Additionally can also use RETURN NO-APPLY.
Again the error in the event procedure during the fill does what I want, which is to stop, but unfortunately the UNDO, THROW eAppError statement in the event procedure isn't raised/caught inside the next catch after the fill event statement.
Yeah. TS said it would be a great enhancement to the product and suggested I log an enhancement request.
Which brings us back to when the ERS will be back online...... At least there is an email address now:
http://web.progress.com/de-de/ers-down.html
I wonder if the Progress web site admins have time to put in new logos to the existing web site, why they don't have time to bring the ERS back up....
Mind you the above isn't very exact to my situation.
Exactly, in your case the error wasn't trapped in any way... it just went straight to the screen
Again the error in the event procedure during the fill does what I want, which is to stop, but unfortunately the UNDO, THROW eAppError statement in the event procedure isn't raised/caught inside the next catch after the fill event statement.
As I've said, the problem is not that you can't catch the error because that should not have been propagated in the first place... otherwise will be simply different behaviour from old to new error handling and imho will just make it even worst, if they decided that returning error is a way to put an end to the fill event but instead of raising the global error status the prodataset error will be set then this should be consistent whether or not the new error handling is used or not.
But, in your case the error was not inhibited... you get to see the progress default error message pop-out on the screen, even if you add no-error to the fill call.
If instead of using throw new AppError(message, number) you use the others constructors which less parameters the error message does not make it to the screen and you get the expected behaviour, the same as when using return error.
undo, throw new AppError(). /* correct */
undo, throw new AppError('error'). /* correct again */
undo, throw new AppError ('error', 123). /* not ok, the error pop-out on the screen when it shouldn't */