Try OpenEdge Now
skip to main content
ABL Reference
ABL Syntax Reference : ON ERROR phrase
 

ON ERROR phrase

Describes the processing that occurs when there is an error in a block. If you are using a REPEAT block or a FOR EACH block, and an error occurs, all of the processing that has been done in the current iteration of the block is undone, and the AVM retries the block iteration where the error occurred. (If the AVM detects that a RETRY of a FOR or iterating DO block would produce an infinite loop, it performs a NEXT instead. For more information, see OpenEdge Getting Started: ABL Essentials.

Syntax

ON ERROR UNDO
  [label1]
  [     , LEAVE [ label2 ]
     |  , NEXT [ label2 ]
     |  , RETRY [ label1 ]
     |  , RETURN [ return-value |
                  ERROR [ return-value | error-object-expression ] |
                  NO-APPLY ]
     |  , THROW
  ]
label1
The name of the block whose processing you want to undo. If you do not name a block with label1, ON ERROR UNDO undoes the processing of the block started by the statement that contains the ON ERROR phrase.
LEAVE [label2]
Indicates that after undoing the processing of a block, the AVM leaves the block labeled label2. If you do not name a block, the AVM leaves the block labeled with label1.
NEXT [label2]
Indicates that after undoing the processing of a block, the AVM executes the next iteration of the block you name with the label2 option. If you do not name a block with the NEXT option, the AVM executes the next iteration of the block labeled with label1.
RETRY [label1]
Indicates that after undoing the processing of a block, the AVM repeats the same iteration of the block you name with the label1 option.
RETRY is the default processing if you do not use LEAVE, NEXT, RETRY, or RETURN.
RETURN ...
Returns to the calling routine, or if there is no calling routine, returns to the OpenEdge Editor. The following table describes various RETURN cases:
Option
Description
return-value
The CHARACTER string you provide is passed to the caller. The caller can use the RETURN-VALUE function to read the returned value.
ERROR
Raises ERROR in the caller and undoes the current subtransaction.
ERROR return-value
Raises ERROR in the caller and undoes the current subtransaction. The CHARACTER string you provide is passed to the caller. The caller can use the RETURN-VALUE function to read the returned value.
The AVM also creates an Progress.Lang.AppError object and stores the return-value in the ReturnValue property.
Note: User-defined functions have different behavior since they must return the data type specified in the definition. See the FUNCTION statement for more information.
ERROR error-object-expression
Raises ERROR in the caller and undoes the current subtransaction.
The specified error object is created and populated according to your code. If this is an Progress.Lang.AppError object, the caller can use the RETURN-VALUE function to read the setting of the ReturnValue property.
NO-APPLY
In a user-interface trigger, prevents the AVM from performing the default behavior for that event.
You cannot specify ERROR within a user-interface trigger block or a destructor. You can specify the NO-APPLY option only within a user-interface trigger block.
THROW
Use this directive to explicitly propagate an error to the enclosing block.
For example, assume you have an enclosing block with a set of CATCH blocks for handling your error types. Within this block is another block with the ON ERROR UNDO, THROW directive. THROW forces any error in this block to the enclosing block.
If there is an CATCH block within the block with the THROW directive and that CATCH explicitly handles the THROWN error, then the error is not propagated to the enclosing block. In this case, the explicit CATCH block handles the error. The THROW directive only applies to errors that are not explicitly caught.
When used, system error messages generated by statements in the block are suppressed and diverted to a Progress.Lang.SysError object. Any error (SysError, AppError, or user-defined) raised within that block will result in an UNDO of the work in that block's iteration as long as there is an active transaction. The error object is thrown to the next enclosing block.

Examples

In r-onerr.p, if you enter a Customer number and the FIND statement is unable to find a Customer with that number, the AVM raises an error. If an error occurs, the ON ERROR phrase tells the AVM to undo anything that was done in the current iteration and start the next iteration. Thus, you see any invalid numbers you enter, and you can continue to the next Customer number you want to enter.
r-onerr.p
REPEAT ON ERROR UNDO, NEXT:
  PROMPT-FOR Customer.CustNum.
  FIND Customer USING Customer.CustNnum.
  DISPLAY Customer.Name Customer.Address Customer.City Customer.State
    Customer.Country.
END.
This block propagates an error from a DO block up to the main procedure block. A CATCH block on the main procedure block handles the error.
r-onErrorThrow01.p
DO ON ERROR UNDO, THROW:
  /* Raises ERROR. The normal error message is diverted to a
     Progress.Lang.SysError error object and thrown to the main block. */
  FIND Customer 1000.
END. /* DO */

MESSAGE "Undisplayed message because of ERROR condition"
VIEW-AS ALERT-BOX BUTTONS OK.

/* CATCH for main (procedure) block */
CATCH eAnyError AS Progress.Lang.ERROR:
MESSAGE "Error message and number retrieved from error object..."
    eAnyError:GetMessage(1) eAnyError:GetMessageNum(1)
VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.

Notes

*For callable blocks, including procedures, user-defined functions, class-based methods, and property accessors use the ROUTINE-LEVEL ON ERROR phrase. All of these blocks have a default ON ERROR setting of UNDO, LEAVE.
*ABL handle methods treat errors as warnings and do not raise error, unless the block containing the code uses a CATCH block. To check for handle method errors in blocks without CATCH, use the NO-ERROR option and check ERROR-STATUS:NUM-MESSAGES for a value greater than zero (0). For handle methods, ERROR-STATUS:ERROR is not set.
*Error objects can be thrown from an AppServer and handled by a CATCH block on an ABL client. To be throwable from an AppServer to an ABL client, user-defined error classes must be defined on both the server and client sides, and the classes must be defined as SERIALIZABLE. For the full list of restrictions on class-based objects that are passed between AppServer and client, see the Parameter passing syntax entry. For more information on error handling in general, see OpenEdge Development: Error Handling.

See also

ON ENDKEY phrase, ON QUIT phrase, ON STOP phrase, RETURN statement, RETURN-VALUE function, ROUTINE-LEVEL ON ERROR UNDO, THROW statement, UNDO statement