Backs out all modifications to fields and variables made during the current iteration of a block, and indicates what action to take next.

Syntax

UNDO
  [ label1 ]
  [     , LEAVE [ label2 ]
      | , NEXT [ label2 ]
      | , RETRY [ label1 ] 
      | , RETURN [ return-value |
                  ERROR [ return-value | error-object-expression ] |
                  NO-APPLY ] 
      | , THROW error-or-stop-object-expression
  ]
label1

The name of the block whose processing you want to undo. If you do not name a block with label1, the AVM undoes the processing of the closest transaction or subtransaction block. In determining the closest transaction or subtransaction block, the AVM disregards DO ON ENDKEY blocks that do not have the ON ERROR or TRANSACTION option.

LEAVE label2

Indicates that after undoing the processing of a block, the AVM leaves the block you name with label2. If you do not name a block, the AVM leaves the block that was undone. After leaving a block, the AVM continues on with any remaining processing in a routine.

NEXT label2

Indicates that after undoing the processing of a block, the AVM does the next iteration of the block you name with label2. If you do not name a block, the AVM does the next iteration of the block that was undone.

RETRY label1

Indicates that after undoing the processing of a block, the AVM repeats the same iteration of the block you name with label1.

Because RETRY in a block without user input results in an infinite loop, the AVM automatically checks for this possibility and converts a RETRY block into a LEAVE block, or a NEXT block if it is an iterating block. This behavior is often referred to as infinite loop protection.

RETURN ...
Returns to the calling routine, if there is one. The following table describes various RETURN options:
Option Description
return-value In procedures and VOID methods, this must be a CHARACTER string. The caller can use the RETURN-VALUE function to read the returned value. For user-defined functions, non-VOID methods and property getters, the value must match the specified return type.
ERROR Undoes the current subtransaction, and raises ERROR in the caller. You cannot specify ERROR within a user-interface trigger block or a destructor.

For user-defined functions see note below.

ERROR return-value Undoes the current subtransaction, and raises ERROR in the caller. The CHARACTER string you provide is available to the caller in the RETURN-VALUE function. The AVM also creates an AppError object and stores the return-value in the ReturnValue property.

For user-defined functions see note below.

ERROR error-object-expression Undoes the current subtransaction, and raises ERROR in the caller. The specified error object instance is thrown to the caller.

For user-defined functions see note below.

NO-APPLY In a user-interface trigger, prevents the AVM from performing the default behavior for the trigger event. Otherwise, the option is ignored.
Note: Using RETURN ERROR in a user-defined function sets the target variable of the function to the Unknown value (?) instead of raising ERROR in the caller. See ABL Error Handling for more detail.
THROW error-or-stop-object-expression

The THROW directive stops the execution of the current block of code, or the current iteration of an iterating block, and raises the ERROR or STOP condition specified in error-or-stop-object-expression. The value of error-or-stop-object-expression must be an error or stop object type.

UNDO, THROW has the following restrictions:

  • UNDO, THROW is not allowed in a CATCH block associated with the main block of an object destructor method. You cannot raise or return an ERROR or STOP condition from a destructor. To do so results in a compile-time error. You can use UNDO, THROW within the code of the destructor itself. In this case, the statement raises the condition in the destructor block and is caught by the ON ERROR or ON STOP directive of the destructor block (which can only be UNDO, LEAVE).
  • The UNDO, THROW statement can itself raise an ERROR condition, or THROW a Progress.Lang.SysError object if it fails. For example, this would happen if the object reference used is not initialized. In this case, the SysError is trapped by the same block that would have trapped the successfully thrown error or stop object.

Example

This example shows how the UNDO, THROW statement specifies and populates an error object, and how the CATCH block handles it:

r-undothrow1.p

FIND Customer 1000 NO-ERROR.
/* Raises error on current block (main block of .p); execution goes to CATCH
   below */
IF ERROR-STATUS:ERROR THEN 
  UNDO, THROW NEW Progress.Lang.AppError("Can't find this customer", 550).

MESSAGE Customer.CustNum. /* This code does not execute if FIND fails */

/* This CATCH is on the main block of r-undothrow1.p */
CATCH eAppError AS Progress.Lang.AppError:
  MESSAGE eAppError:GetMessage(1) eAppError:GetMessageNum(1).
END CATCH.

Notes

  • You can also specify UNDO processing for a block by using the ON ERROR, ON STOP, and ON ENDKEY phrases with a block statement.
  • Class-based error or stop objects can be thrown from an OpenEdge application server and handled by a CATCH block on an ABL client. To be throwable from an OpenEdge application server to an ABL client, any user-defined error classes must be defined as SERIALIZABLE on both the server and client sides. In addition, note that any STOP condition messages are written to the server log file, even if a stop object with the messages is caught on the client. For the full list of restrictions on class-based objects that are passed between server and client, see the Parameter passing syntax entry.
  • If you do not supply an action (LEAVE, NEXT, RETRY, RETURN, or THROW) with the UNDO statement, the AVM applies the default undo action for the type of block being undone. The default action is determined by the block context and may result in retrying the block or leaving or advancing an iteration of the block. Because the default action is implicit and context-dependent, Progress Software recommends that you always specify an action with the UNDO statement for clarity and consistency.
  • For more information on the UNDO statement, see Develop ABL Applications. For more information on error and stop handling in general, see ABL Error Handling.

See also

ON ENDKEY phrase, ON ERROR phrase, RETRY function, RETURN statement, ROUTINE-LEVEL ON ERROR UNDO, THROW statement