try

A try block specifies a ProcScript instruction, or set of instructions, that could raise an exception.

try
    <ProcScript that may throw an exception>
{catch} {ErrorNumber1 {, ErrorNumberN}}
    <Procscript that handles the error >}
{rethrow}
{finally}
     <ProcScript that will always execute, regardless of whether an error occurred or not>
endtry

Return Values

None.

Use

Allowed in all component types.

Description

A try block is used to specify code that can throw an exception. Each try block must have an endtry statement to mark the end of the block.

You can use a try block with no catch or finally statements in the same way as a throws declaration, to declare that any $procerror with a negative value that occurs from code within the block will be regarded as an exception.

A try block is typically used with a catch block contained in it that handles errors in the code and prevent the application from crashing at runtime. It tries a block of code that could give a $procerror. If the error occurs, an exception is thrown, which can be caught and handled by a catch block. A try block can have one or more associated catch blocks. For example:

try
... ; code that might raise system exceptions or custom exceptions
catch -2, -4, -10050
... ; Handle these IO related exceptions
catch -10048
... ; Handle this custom exception
catch -10054
... ; Handle this other custom exception
catch  ; Catch any other errors
... ; Handle any other exceptions
endtry

It is also possible to nest a try...catch...endtry block inside another try block or inside a catch block.

When an exception is thrown, code execution continues in one of the associated catch blocks, if there is an applicable one. If not, the exception bubbles up to a higher level, such as the next try-level or to the caller of the module.

A catch block can also optionally contain a rethrow statement. This allows you to rethrow an exception that was caught in the catch block.

A try block can also contain a finally statement, which declares any ProcScript inside a try block that must be executed, regardless of whether an exception occurs or not.

Note: A try block can have one or more catch blocks, or a finally statement, or both.

The goto statement and ProcScript label are not allowed inside a try, catch, or finally block, and will result in a compilation error.

Exception Bubbling

When an exception is thrown, code execution continues in one of the associated catch blocks, if there is an applicable one. If not, the exception bubbles up to a higher level, such as the next try-level or to the caller of the module.

Letting uncaught exceptions bubble up is a useful technique for finding problems during development.

For example, the following code does an ordinary retrieve in the try block, and catches the exceptions that are raised if the entity has no occurrences (-2) or table does not exist (-4). Any other exception is thrown to the calling module because the checkDataExists entry contains a throws declaration.

entry checkDataExists
throws ; this module throws an exception if an error is returned
returns boolean
  try
    retrieve "MYENTITY"
  catch <UIOSERR_OCC_NOT_FOUND>, <UIOSERR_OPEN_FAILURE>  ; -2, -4
    return <FALSE>  ; No data available
  endtry 
  return <TRUE> ; Data available
end

If you have made a typo, such as misspelling the entity name, you are confronted with an exception at an early stage in the development process.

Nested Try-Catch Blocks

Exceptions can also bubble up in nested catch blocks.

entry MY_ENTRY
  try
    try
      call MY_OTHER_ENTRY()
    catch -4
    ... ; Handle error -4
    endtry
    putmess "After the inner endtry $procerror is %%($procerror)"
  catch  ; Catch all 
    putmess "The catch-all of the outer try: $procerror is %%($procerror)"
  endtry
 end

For example, if the call to MY_OTHER_ENTRY throws exception -5, the following would end up in the message frame:

The catch-all of the outer try: $procerror is -5

Related Topics