FILL event cannot throw an error

Posted by ericg on 20-May-2011 11:52

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.   

All Replies

Posted by Tim Kuehn on 23-May-2011 12:09

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.

Posted by Admin on 24-May-2011 12:28

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.

Posted by ericg on 24-May-2011 15:01

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.

Posted by ericg on 24-May-2011 20:04

TS mentioned can also check the ProDataSet ERROR attribute.

Posted by Admin on 25-May-2011 06:07

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?

Posted by ericg on 25-May-2011 13:02

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.

Posted by Admin on 25-May-2011 13:07

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....

Posted by Admin on 25-May-2011 13:45

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 */

This thread is closed