How to retry from within catch block

Posted by cverbiest on 05-Jun-2019 14:29

I'm trying to retry from within a catch block

The manual https://documentation.progress.com/output/ua/OpenEdge_latest/index.html#page/dvref/catch-statement.html states

The code in any CATCH block can contain an explicit flow-of-control directive, meaning LEAVE, NEXT, RETRY, RETURN, or THROW. (RETRY and THROW require UNDO.) Since CATCH is an undoable block, LEAVE, NEXT, and RETRY without a label will apply to the CATCH block itself and not the associated block.

If you want LEAVE, NEXT, or RETRY to apply to the associated block of a CATCH block, you must use the existing label syntax for these statements.
An explicit UNDO, THROW in a CATCH block causes the AVM to raise ERROR or STOP in the block that encloses the associated block of the CATCH block; not the associated block itself.

However if I run my sample code I get a compilation error.

Seems like a bug to me, or am I missing something ?

---------------------------
Syntax check:
Cannot UNDO to block 'tryblock' from within a CATCH block for block 'tryblock'. (14134)
---------------------------

define variable lInt as integer no-undo.
define variable lText as character no-undo init "abc123".

tryblock:
do on error undo, retry:
    lint = integer(lText).
    catch err as Progress.Lang.Error :
         if lText > "" 
         then do:
             substring(lText, 1, 1) = "".
             undo tryblock, retry tryblock.
         end.
    end catch.
end.       

All Replies

Posted by cverbiest on 05-Jun-2019 14:42

Following variant compiles but it does not do what I expect either

I expect

  • try abc123
  • next
  • try bc123
  • next
  • try c123
  • next
  • try 123
  • end 123 123

instead I get

  • try abc123
  • next
  • end 0 bc123

define variable lInt as integer no-undo.
define variable lText as character no-undo init "abc123".

tryblock:
repeat while lTExt > "" on error undo, next:
    message "try" lText     view-as alert-box.
    lint = integer(lText).
    catch err as Progress.Lang.Error :
         if lText > "" 
         then do:
            substring(lText, 1, 1) = "".
            message "next"             view-as alert-box.
		next tryblock.
         end.
         
    end catch.
end.       

message "end" lInt lText view-as alert-box.

Posted by jquerijero on 05-Jun-2019 16:13

What happens if you replace REPEAT WHILE with DO WHILE?

Posted by Laura Stern on 05-Jun-2019 16:25

There are definitely bugs using UNDO in a CATCH block.  It definitely does not behave as documented. Though I thought it did work when a label is used.  On the other hand, once the CATCH block runs, the associated block (tryblock in this case) has already been undone.  So not sure saying UNDO in this context actually makes any sense.

How about something like this instead:

do while substring(lText, 1,1) >= 'a':

   substring(lText, 1, 1) = "".

end.      

Posted by Laura Stern on 05-Jun-2019 16:27

You can't use DO WHILE with the CATCH because unless you RETRY, you will still leave the block after the error happens.

Posted by jquerijero on 05-Jun-2019 16:46

You can still fallback to using the NO-ERROR approach if CATCH is not playing well.

Something like:

lint = integer(lText) NO-ERROR

IF lint <> ? THEN

 LEAVE.

Posted by cverbiest on 06-Jun-2019 06:56

[mention:04fbfb2e92784123a464ff2aade602b1:e9ed411860ed4f2ba0265705b8793d05] are these bugs already logged or is it better that I create a tech support case for this ? I did my tests in 11.7.4

As far as the alternatives are concerned, my actual use case doesn't look anything like the sample code I posted here.

I'll code it some other way but I was mainly wondering if I missed something  in how to do a retry from within a catch block

Posted by Torben on 06-Jun-2019 09:12

Somethink like the following should do what you want:

tryblock:
do while TRUE on error undo, retry:
   do on error undo, throw:
    lint = integer(lText).
    LEAVE tryblock.
    catch err as Progress.Lang.Error :
         if lText > ""
         then do:
             substring(lText, 1, 1) = "".
             NEXT tryblock.
         end.
    end catch.
   end.
end.

Posted by napmo on 06-Jun-2019 09:33

There is an infinite loop protection for UNDO, RETRY block.

you should use the RETRY function or have user interaction before the error. If not it is replaced by undo, next

see :

knowledgebase.progress.com/.../What-is-Infinite-Loop-Protection

Posted by Laura Stern on 06-Jun-2019 12:32

Infinite loop protection, indeed!  THANK YOU.  I never think of that.  I was thinking that getting kicked out of the DO WHILE after a CATCH was also wrong.  I was starting to get depressed!  

In any case, Torben showed the right solution.  And sorry - I never addressed the question of the error 14134.  If you added yet another block level and lableled that as tryblock, it would compile.  As I said, the associated block is already undone.  I believe that is why.

tryblock:

do on error undo, leave:  /* extra level here */

   do on error undo, retry:

       lint = integer(lText).

       catch err as Progress.Lang.Error :

            if lText > ""

            then do:

                substring(lText, 1, 1) = "".

                undo tryblock, retry tryblock.

            end.

       end catch.

   end.  

END.    

This thread is closed