Input blocking statement is invalid while executing a user-defined function - Forum - OpenEdge General - Progress Community

Input blocking statement is invalid while executing a user-defined function

 Forum

Input blocking statement is invalid while executing a user-defined function

  • Hello,

    Is it true that older Progress client versions (9.1C or older) have problems with MESSAGE statements in user-defined functions (Error 2780)?

    That's the rumour that goes here (is a MESSAGE an 'input-blocking statement'?) and because some of our customers still use 9.1C we try to stay away from using MESSAGE's in user-defined functions (or procedures (with MESSAGE's in them) that are called from user-defined functions), we always try to replace them with procedures.

    I have now come to a point where MESSAGE statements are crucial and used in functions, but I would really be certain that this works as expected on older clients before putting it in production...

    Thanks for any answers

    Lieven

  • Within a function, you cannot define any input-blocking statements, such as a WAIT-FOR statement or any statement that prompts the user for input.

    If your MESSAGE statements do not use VIEW-AS ALERT-BOX, BUTTONS you should be okay.

    See:

    http://tinyurl.com/y5aro5

    http://tinyurl.com/y4pjup

    Message was edited by:

    Salvador Vinals

  • So in that case the following can pose problems?

    MESSAGE "File not found!"

    VIEW-AS ALERT-BOX INFO BUTTONS OK.

    /* or */

    DEFINE VARIABLE pOk AS LOGICAL NO-UNDO.

    MESSAGE "Continue"

    VIEW-AS ALERT-BOX INFO BUTTONS YES-NO UPDATE pOk.

    IF pOk THEN

    /* ... */

    ELSE

    /* ... */

    Or is it safe to use these, because I don't get any runtime errors?

  • These two MESSAGE statements require user input. Avoid them in UDFs.

  • The thing is, I'm trying to use John Sadd's implementation of Exception Handling in 4GL and he effectively uses the MESSAGE statement as stated above (in an internal procedure called from a UDF) to display the exceptions to the user. Does that mean I can't be 100% certain that this won't generate 2780 error's?

    John's code

    http://tinyurl.com/yalcyr

    I'm not easily satisfied, sorry

  • Salvador ... may I recommend tinyurl.com? Those long URLs do funny things to the format of the thread!

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • May I recommend that you download the AutoEdge code and check out the exception handling mechanism there? It doesn't have all the nice features of my exception and condition handling classes ( http://www.oehive.org/ExceptionClass ), but it is probably closer to what you are already doing.

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • Thanks Salvador! Much better!

    Consulting in Model-Based Development, Transformation, and Object-Oriented Best Practice  http://www.cintegrity.com

  • Thanks, I'll look into AutoEdge, I hope it is usable in a Progress 9 environment...

    But my real question isn't answered yet: Can I use a MESSAGE "Hello" VIEW AS ALERT-BOX... statement in UDF's and be certain it won't generate 2780 errors with our clients (here it seems to work...)

    edit: The AutoEdge exception handling IS John Sadd's work mentioned earlier! He uses a UDF DisplayException() that calls internal procedure DisplayExceptionProc that displays a message. When you assume that the message statement is a blocking statement, than that isn't allowed...

    Message was edited by:

    lieven

  • Hi Lieven,

    MESSAGE is not an input-blocking statement (strange that Salvador didn't know, since in the old days we complained a lot about this constraint

    Run this code and see for yourself, the function with MESSAGE runs fine:

    DEFINE TEMP-TABLE ttSample NO-UNDO

    FIELD iKey AS INTEGER.

    FUNCTION CreateKey RETURNS INTEGER(INPUT lpInputBlocking AS LOGICAL):

    IF lpInputBlocking THEN

    PROCESS EVENTS.

    ELSE

    MESSAGE "Hi there" VIEW-AS ALERT-BOX.

    RETURN 10.

    END FUNCTION.

    CREATE ttSample.

    MESSAGE "Call CreateKey(FALSE)" VIEW-AS ALERT-BOX.

    ASSIGN iKey = CreateKey(FALSE).

    MESSAGE "Call CreateKey(TRUE)" VIEW-AS ALERT-BOX.

    ASSIGN iKey = CreateKey(TRUE).

  • Great demonstration.

    Is 'MESSAGE is not an input-blocking statement ' documented anywhere? I could find nothing, and didn't want to pursue msgboxa winapi mechanics.

    I've often wondered the same as lieven, and I've never used it for Salvador's reasons, but also because my personal, arguably religious opinion is that using functions for UI, or as substitutes for procedures is 'aesthetically incorrect' (ie. likely to cause future issues).

  • Is 'MESSAGE is not an input-blocking statement '

    documented anywhere? I could find nothing, and didn't

    want to pursue msgboxa winapi mechanics.

    I think it's defined somewhere. But if you think about it, it makes sense that a messagebox is an exception: this statement can never invoke another 4GL statement. It's blocking at the MESSAGE-statement, so the runtime doesn't have to worry about reentrant code...

  • Progress documents in several places the 7 statements that are illegal in user-defined functions, non-void methods, and property accessor implementations. Specifically, the FUNCTION statement contains a note identifying these illegal statements and the help text for error 5622 also provides this information. In fact the help text states that the MESSAGE statement is NOT a statement that blocks for user input and therefore is legal in user-defined functions.

    Error 5622 states:

    UPDATE, SET, PROMPT-FOR, CHOOSE, INSERT, WAIT-FOR, and READKEY statements are not permitted inside a user-defined function, or inside a non-void method or a property GET or SET body. (5622)

    You have an I/O blocking statement inside a user-defined function, a non-void method, or the body of a property accessor. These types of routines cannot tolerate blocking for user input. You need to remove the statement, or turn the user-defined function into an internal procedure, or make the method VOID. Note that a MESSAGE with an ALERT-BOX is not I/O blocking.

    Evan Bleicher

    Sr. Development Manager

    Progress Software

  • Progress documents in several places the 7 statements

    that are illegal in user-defined functions, non-void

    methods, and property accessor implementations.

    The documentation generally uses weasel words like 'Input blocking statements include...', which is why this question arises.

    Specifically, the FUNCTION statement contains a note

    identifying these illegal statements

    Yes, it is rather more specific there, though no explicit exclusion of alert-boxes.

    and the help

    text for error 5622 also provides this information.

    Nope.

    In fact the help text states that the MESSAGE

    statement is NOT a statement that blocks for user

    input and therefore is legal in user-defined

    functions.

    Nope.

    Error 5622 states:

    You have an I/O blocking statement inside a

    user-defined function, a non-void method, or the body

    of a property accessor. These types of routines

    cannot tolerate blocking for user input. You need to

    remove the statement, or turn the user-defined

    function into an internal procedure, or make the

    method VOID. Note that a MESSAGE with an

    ALERT-BOX is not I/O blocking.

    You obviously have the deluxe help. Mine (9.1D07) states (similarly, but note the important omission):

    You have an I/O blocking statement inside a user-defined function. User-defined functions cannot tolerate blocking for user input. You need to remove the statement from the user-defined function, or turn the user-defined function into an internal procedure.

    c

    (Ends there with isolated 'c')

    Assuming no corruption in my install, I guess it's a documentation bug in pre OE editions. Thanks for the pointers.

  • But if you think

    about it, it makes sense that a messagebox is an

    exception: this statement can never invoke another

    4GL statement. It's blocking at the

    MESSAGE-statement, so the runtime doesn't have to

    worry about reentrant code...

    Thanks, will mull this over another time, but it's 2.30AM here at the moment, and this is a little beyond me right now...