Structured Exception Handling Sample

File: ...\Samples\Solution\Toledo\TryCatch.scx

You can implement structured exception handling using the TRY...CATCH...FINALLY error handling structure to run a particular block of statements if a specified exception occurs when your program runs. When an error, or exception, occurs, an Exception object is created.

This sample demonstrates how to catch exceptions using the TRY and CATCH blocks, clean up resources using the FINALLY block, and throwing, or escalating, exceptions using a THROW statement.

For more information, see Structured Error Handling, TRY...CATCH...FINALLY Command and Exception Object.

Catching Exceptions

In this sample, you can choose an error, or exception, you want to cause in the TRY block and view the properties for the Exception object generated from the exception.

To raise an exception

  • In the CATCHing Exceptions tab, select the error you want from the drop-down list and click Execute TRY block.

The CATCH block runs and displays the Exception object properties.

The following code shows the error handling structure in this particular sample. Usually, code that might generate an exception appears in the TRY block; however, the ERROR command is called specifically to show how the flow of control is passed to the CATCH block only when an exception occurs.

You can use the ExceptionUserValue property to store any additional information about the error.

TRY
   ERROR nErrorCode
CATCH TO myException
   myException.UserValue = "I can handle this."
ENDTRY

Cleaning Up Resources

The FINALLY block usually cleans up any resources allocated by the TRY block and is always the last code to run before control leaves the TRY...CATCH...FINALLY structure.

To observe how FINALLY executes after all other code

  • In the Using FINALLY tab, select an option or type a table name and path in the combo box and click TRY.

The following code demonstrates how FINALLY executes after all other code.

TRY
   lnPrevArea = SELECT()
   USE CUSTOMERS IN 0 EXCLUSIVE 
* Handle when file does not exist.
CATCH TO myException WHEN myException.ErrorNo = 1 
* Handle when file is in use.
CATCH TO myException WHEN myException.ErrorNo = 3 
* Handle when file access is denied.
CATCH TO myException WHEN myException.ErrorNo = 1704  
* Catch everything else.
CATCH TO myException 

* Code in FINALLY block always executes.
FINALLY
IF USED('CUSTOMERS')
      USE IN CUSTOMERS
   ENDIF
   SELECT (lnPrevArea)
ENDTRY

Throwing Exceptions

To escalate an exception to a higher-level error handler, use a THROW statement in a CATCH block.

This sample uses nested TRY blocks. The inner TRY block can handle only the first error. For subsequent errors, the inner TRY block escalates the Exception object to the outer TRY block. When a specific exception is thrown, specifically THROW oMyException in this example, the UserValue property of the caught exception in the outer block contains the thrown exception from the inner block.

TRY
   * Run some code.
   TRY
      * Error occurs.
      ERROR 3
      CATCH TO InnerException WHEN InnerException.ErrorNo = 1
      InnerException.UserValue = "INNER TRY: I can handle this."
      CATCH TO InnerException
      InnerException.UserValue = "INNER TRY: I can't handle this."
      * Error cannot be handled so escalate to outer TRY block.
      THROW InnerException
   ENDTRY
CATCH TO OuterException
* In this case, when the exception is escalated, the caught exception's 
* UserValue property contains the escalated exception from inner TRY.
? OuterException.UserValue.UserValue
ENDTRY

You can also throw a string message. In this case, the string message is stored in the UserValue property of the outer exception:

TRY   
   * Run some code.
   TRY
      * Error occurs.
        ERROR 1
   CATCH
      THROW "INNER TRY: I can't handle this one."
   ENDTRY
CATCH TO OuterException 
   ? OuterException.UserValue
ENDTRY      

See Also

Solutions Samples