CATCH block may only be associated with an undoable block. (

Posted by twc on 31-Jan-2017 14:54

EDIT:  better code image:  http://www.timcollins.com/images/catch_OE_error_14140.png  - sorry, color highlighting after [Insert Code using Syntax Highlighter] looked good in "Preview" mode, but not so good in the post.

Hello All,

Error makes sense and thus "do" requires an "on error" phrase.  All good.

... as long as "on error"s undo directive does not have a label ...  ???

  • change "do" to a "repeat", all good
  • remove labels, put undo statement (with same directives) in catch processing, all good
  • make explicit transaction, all good - guess "on error" alone not good enough?

Am I missing an intricate detail of "on error"?  Bug?

Thanks,

Tim

Example illustrating the error (OE 11.6):



block-level on error undo, throw. using Progress.Lang.AppError. define variable var1 as character no-undo. MAIN_BLK: repeat: update var1. do on error undo MAIN_BLK, retry MAIN_BLK: run pValidation(input var1). catch ae as AppError: message ae:getMessage(1) view-as alert-box. end catch. end. end. procedure pValidation: define input parameter pVar as character no-undo. if pVar = "A" then undo, throw new AppError("We don't like 'A'",999). end.


All the following compile/run successfully.


block-level on error undo, throw.
using Progress.Lang.AppError.

define variable var1 as character no-undo.

MAIN_BLK:
repeat:
   update var1.
   INNER_BLK:
   repeat on error undo MAIN_BLK, retry MAIN_BLK:
      run pValidation(input var1).
      leave INNER_BLK.
      catch ae as AppError:
          message ae:getMessage(1) view-as alert-box.
          undo MAIN_BLK, retry MAIN_BLK.
      end catch.
   end.
end.

procedure pValidation:
   define input parameter pVar as character no-undo.
   if pVar = "A" then
      undo, throw new AppError("We don't like 'A'",999).
end.

block-level on error undo, throw.
using Progress.Lang.AppError.

define variable var1 as character no-undo.

MAIN_BLK:
repeat:
   update var1.
   do on error undo, leave:
      run pValidation(input var1).
      catch ae as AppError:
          message ae:getMessage(1) view-as alert-box.
          undo MAIN_BLK, retry MAIN_BLK.
      end catch.
   end.
end.

procedure pValidation:
   define input parameter pVar as character no-undo.
   if pVar = "A" then
      undo, throw new AppError("We don't like 'A'",999).
end.

block-level on error undo, throw.
using Progress.Lang.AppError.

define variable var1 as character no-undo.

MAIN_BLK:
repeat:
   update var1.
   do TRANSACTION on error undo MAIN_BLK, leave MAIN_BLK:
      run pValidation(input var1).
      catch ae as AppError:
          message ae:getMessage(1) view-as alert-box.
      end catch.
   end.
end.

procedure pValidation:
   define input parameter pVar as character no-undo.
   if pVar = "A" then
      undo, throw new AppError("We don't like 'A'",999).
end.

Posted by Laura Stern on 01-Feb-2017 08:30

I think what is happening is that because you have the labels which are saying to undo/retry the REPEAT block, rather than the DO block, that the DO block itself is not seen as an undoable subtraction block.  That is basically the rule - that a CATCH can only be associated with an undoable block.  So that explains why if you remove the labels, it works since then it is the DO block that is undoable.

Apparently, replacing DO with REPEAT has the same effect even if you leave the labels.  REPEAT blocks are always undoable.  Ditto for TRANSACTION blocks.  Simple DO blocks are not.

I agree it is not very intuitive!  But I believe it is correct - even though at first I thought it was a bug :-).

All Replies

Posted by Laura Stern on 01-Feb-2017 08:30

I think what is happening is that because you have the labels which are saying to undo/retry the REPEAT block, rather than the DO block, that the DO block itself is not seen as an undoable subtraction block.  That is basically the rule - that a CATCH can only be associated with an undoable block.  So that explains why if you remove the labels, it works since then it is the DO block that is undoable.

Apparently, replacing DO with REPEAT has the same effect even if you leave the labels.  REPEAT blocks are always undoable.  Ditto for TRANSACTION blocks.  Simple DO blocks are not.

I agree it is not very intuitive!  But I believe it is correct - even though at first I thought it was a bug :-).

Posted by twc on 01-Feb-2017 16:21

Now there's an intricate detail!

You're right, not intuitive, but you've clarified the issue.   It's bitten me many times with validation specific catch processing - used TRANSACTION (begrudgingly) in the past.  Documentation notes for ON ERROR and CATCH didn't help.  When I really dug in yesterday and REPEAT and UNDO (statement) both also worked, it left me scratching my head.  REPEAT with immediate leave (kludge) and TRANSACTION both misrepresent the actual "functional processing" - I always disliked using TRANSACTION.  UNDO statement within CATCH is good.

And now it all makes sense ... it certainly didn't before your reply.

Thanks Laura!

This thread is closed