The RETURN ERROR statement is another way of raising an ERROR condition. The full syntax of the RETURN statement is shown below, though here we are only discussing the RETURN ERROR options.

You can use the ERROR option in a procedure, database trigger block, class-based method, constructor, or property accessor. However, you cannot use it in a user-interface trigger block or destructor to raise ERROR outside of that block. This results in a compiler error. More information about conditions in destructors are discussed in Throw a condition out of a destructor. You also cannot use RETURN ERROR in a user-defined function to raise ERROR outside of that block. This is explained in more detail in Raise ERROR to the caller of a user-defined function.

Note that if an error is returned from any procedure, method, or user-defined function, the values of any OUTPUT or INPUT-OUTPUT parameters are not returned to the caller.

Syntax

RETURN 
    [ return-value |
    ERROR [ error-return-value | error-object-expression ] |
    NO-APPLY ].
error-return-value
A character expression.
error-object-expression
Any expression that results in an instance of an error or stop object.
Aside from being a stand-alone statement, the RETURN phrase, with the same options, is also available on the following language elements:
  • ON ENDKEY phrase
  • ON ERROR phrase
  • ON QUIT phrase
  • ON STOP phrase
  • UNDO statement

Regardless of the options, when RETURN ERROR executes, execution returns to the caller of the current procedure, method, constructor, or property accessor, and ERROR is raised in the caller. If it occurs in a database trigger, ERROR is raised on the statement that caused the database event. Because the AVM returns before raising error, the block containing the RETURN statement or phrase is not undone. The behavior in the caller is then dictated by that block’s error-handling capabilities (error directive or CATCH block).

Note: The remainder of this section does not apply to user-defined functions.

The AVM does the following when the RETURN ERROR statement executes:

  • If neither an error-return-value nor an error-object-expression is supplied, the AVM creates an instance of Progress.Lang.AppError with no error message set and the ReturnValue property set to the empty string. The value for the RETURN-VALUE built-in function is also set to the empty string.
  • If an error-return-value expression is supplied, the AVM creates the AppError object and sets its ReturnValue property. No error message is set in the object. It also sets the value for the RETURN-VALUE built-in function.
  • If an instance of an error object is supplied, the AVM does not create a new instance.
  • In all cases, the AVM returns and behaves as if this object was thrown on the invoking statement.

In the caller, if NO-ERROR is used on the invoking statement, any error messages in the object are transferred to the ERROR-STATUS system handle, ERROR-STATUS:ERROR is set to TRUE, and the error object instance is discarded. Any custom information in the error object is lost.

Otherwise (if NO-ERROR is not used on the invoking statement) the error object is handled in the usual way. If there is a relevant CATCH block, the error is caught. Otherwise the block’s error directive takes effect. If default error handling is in place, any error message is displayed to the output device. But if there is no error message stored in the object, no display is made.

Example

The following example shows how RETURN ERROR is used to return a custom AppError to a caller using NO-ERROR:

DEF VAR ix AS INT.

RUN proc NO-ERROR.  
IF ERROR-STATUS:ERROR THEN
DO:
    DO ix = 1 TO ERROR-STATUS:NUM-MESSAGES: /* this will be 2 */           
        MESSAGE ERROR-STATUS:GET-MESSAGE(ix) ERROR-STATUS:GET-NUMBER(ix).
    END.            
END.

PROCEDURE proc:
    DEFINE VAR err AS PROGRESS.Lang.AppError.
        
    err = NEW PROGRESS.Lang.AppError("The car cannot be rented",1).
    err:AddMessage ("No driver's license was provided", 98).

    RETURN ERROR err.
END.