CATCH statement

Defines an ERROR or STOP condition-handling end block for any undoable ABL block. An end block is an ABL block that can occur only within and at the end of another block. The block containing the end block is known as the associated block. End blocks must occur between the last line of executable code in the associated block and its END statement.

A CATCH block executes when an ERROR or STOP condition raised in the associated block is compatible with the error or stop type that is specified in the CATCH statement. To be compatible, the error or stop type must be the type specified in the CATCH statement for an object that is thrown in the associated block, or it must be a sub-type (sub-class) of the specified type that is thrown. The CATCH block thus executes when a thrown object of the specified error or stop type is caught by the CATCH statement, at which point the object can then be processed (handled) in the CATCH block.

For ERROR condition-handling, CATCH blocks for error types (error CATCH blocks) take precedence over any implicit or explicit ON ERROR directives specified for the associated block. Similarly for STOP condition-handling, CATCH blocks for stop types (stop CATCH blocks) take precedence over any implicit or explicit ON STOP directives specified for the associated block.

This is the syntax for the CATCH statement and its related blocks:

Syntax

block-statements
    CATCH error-or-stop-variable AS [ CLASS ]error-or-stop-class-type:
        catch-logic
    END [ CATCH ] .
[block-end-statement]
block-statements
All of the statements of an enclosing associated ABL block, except for its block-end-statement. The enclosing associated block can be any ABL block, including another CATCH block.
error-or-stop-variable
The variable name that references the error object generated by the error condition. Typically, you do not define the error-or-stop-variable ahead of time with the DEFINE VARIABLE statement. The AVM recognizes a new variable name on the CATCH statement as a new error-or-stop-variable definition. Each CATCH in an associated block must have a unique error-or-stop-variable. You can reuse an error-or-stop-variable name in a different associated block, as long as its type is compatible with the new definition.
[ CLASS ]error-or-stop-class-type
A compatible class type name for a given error or stop type where the object:
  • Implements Progress.Lang.Error, for example:
    • Progress.Lang.SysError or a built-in subclass (system errors)
    • Progress.Lang.AppError or a user-defined subclass (application errors)
    • System.Exception or a .NET subclass (.NET Exceptions)
    • Progress.Lang.StopError (STOP conditions raised for certain system errors)
  • Is Progress.Lang.Stop or a built-in subclass (STOP conditions raised for supported ABL features, such as a STOP-AFTER time-out on a DO, FOR, or REPEAT statement)
Note: Therefore, if you specify Progress.Lang.SysError, this one block can handle all ERROR conditions raised from a system error and all STOP conditions raised from a system error. If you specify Progress.Lang.Error, this one block can handle all ERROR conditions (including system errors, application errors, and .NET Exceptions) and all STOP conditions raised from a system error. If you specify Progress.Lang.Stop, this one block can handle all STOP conditions raised from supported ABL features.
Optionally, you can provide the CLASS keyword.
catch-logic
All statements allowed in a CATCH block, which can include any valid ABL statement. For more information on CATCH block execution, see the Notes of this reference entry.
block-end-statement
For all associated ABL blocks except a main external procedure block, the END statement terminates and encloses the associated block of the CATCH block. External procedure blocks have no terminating END statement.

Examples

The following code fragment shows CATCH blocks for associated DO blocks:

DO ON ERROR UNDO, LEAVE:
  FIND FIRST Customer NO-LOCK WHERE Customer.CustNum = 5000.

  CATCH oneError AS Progress.Lang.SysError:
    MESSAGE oneError:GetMessage(1) VIEW-AS ALERT-BOX BUTTONS OK.
  END CATCH.

  CATCH twoError AS Progress.Lang.ProError:
    MESSAGE twoError:GetMessage(1) VIEW-AS ALERT-BOX BUTTONS OK.
  END CATCH.
END. /* FIRST DO */

DO ON ERROR UNDO, LEAVE:
  FIND FIRST Customer NO-LOCK WHERE Customer.CustNum = 6000.

  /* You can reuse an error-or-stop-variable from a different 
     associated block */
  CATCH oneError AS Progress.Lang.SysError:
    MESSAGE oneError:GetMessage(1) VIEW-AS ALERT-BOX BUTTONS OK.
  END CATCH.

  /* NOT LEGAL: Each CATCH block in an associated block must have a unique
     error-or-stop-variable. */
  CATCH oneError AS Progress.Lang.ProError:
    MESSAGE oneError:GetMessage(1) VIEW-AS ALERT-BOX BUTTONS OK.
  END CATCH.
END. /* SECOND DO */

In the following example, the CATCH block will catch any ABL system error or a STOP condition raised by an unexpected system error:

DEFINE VARIABLE iCust AS INTEGER NO-UNDO INITIAL 5000.

FIND Customer NO-LOCK WHERE Customer.CustNum = iCust. /* Will fail */

/* Won't execute because FIND fails */
MESSAGE "Customer found" VIEW-AS ALERT-BOX BUTTONS OK. 

/* The associated block for this CATCH block is the main block of the .p */
CATCH eSysError AS Progress.Lang.SysError:
  MESSAGE eSysError:GetMessage(1) VIEW-AS ALERT-BOX BUTTONS OK.
END CATCH.

Notes

See also

BLOCK-LEVEL ON ERROR UNDO, THROW statement, ON ERROR phrase, ON STOP phrase, Progress.Lang.Error interface, Progress.Lang.Stop class, RETURN statement, ROUTINE-LEVEL ON ERROR UNDO, THROW statement, UNDO statement