FutureBasic Logo

<<    Index    >> FutureBasic

try   statement

end try

catch ( exceptionObject )
end catch

end finally

throw [exceptionObject]

Compiler support for exceptions is based on four compiler directives:

try - Defines a block of code that is an exception handling domain: code that can potentially throw an exception. The try block must end with an end try statement.

catch() - Defines a block containing code for handling the exception thrown in the try block. The parameter of catch is the exception object thrown locally; this is usually an ExceptionRef, but can be other types of object, such as a CFStringRef. The catch block must end with an end catch statement.

finally - Defines a block of related code that is subsequently executed whether an exception is thrown or not. The finally block must end with an end finally statement.

throw - Throws an exception; this directive is identical in behavior to the ExceptionRaise function. Cocoa applications should throw only ExceptionRef objects.

The try, catch, and finally directives constitute a control structure. The code in the try block is the exception handling domain; the code in a catch block is a local exception handler; the finally block of code is a common "housekeeping" section. In Figure 1, the normal flow of program execution is marked by the green arrow; the code within the catch block is executed only if an exception is thrown - either by the try block or one further down the call sequence. The throwing (or raising) of an exception causes program control to jump to the first executable line of the catch block. After the exception is handled, control "falls through" to the finally block; if no exception is thrown, control jumps from the try block to the finally block.

Figure 1 Flow of exception handling using compiler directives
Figure 1

Where and how an exception is handled depends on the context where the exception was raised (although most exceptions in most programs go uncaught until they reach the top-level handler installed by the shared Application object). In general, an exception object is thrown (or raised) within the domain of an exception handler. Although you can throw an exception directly within a local exception handling domain, an exception is more likely thrown (through @throw or raise) indirectly from a method invoked from the domain. No matter how deep in a call sequence the exception is thrown, execution jumps to the local exception handler (assuming there are no intervening exception handlers, as discussed in Nesting Exception Handlers). In this way, exceptions raised at a low level can be caught at a high level.

Throwing Exceptions
Once your program detects an exception, it must propagate the exception to code that handles it. This code is called the exception handler. This entire process of propagating an exception is referred to as "throwing an exception" (or "raising an exception" ). You throw (or raise) an exception by instantiating an ExceptionRef object and then doing one of two things with it: • Using it as the argument of a throw compiler directive • Sending it a raise message The following example shows how you throw an exception using the throw directive (the raise alternative is commented out):

ExceptionRef myException
myException = fn ExceptionWithName( @"FileNotFoundException", "File Not Found on System", NULL )
throw myException
ExceptionRaise( myException ) // equivalent to above directive

Typically you throw or raise an exception inside an exception-handling domain, which is a block of code marked off by the try compiler directive.

Within exception handling domains you can re-propagate exceptions caught by local exception handlers to higher-level handlers either by sending the ExceptionRef object another raise message or by using it with another throw directive. Note that in catch exception-handling blocks you can rethrow the exception without explicitly specifying the exception object.

There is a subtle aspect of behavior involving re-thrown exceptions. The finally block associated with the local catch exception handler is executed before the throw causes the next-higher exception handler to be invoked. In a sense, the finally block is executed as an early side effect of the throw statement. This behavior has implications for memory management.

The above text is from the Apple™ document "Introduction to Exception Programming Topics for Cocoa" with minor changes made that are relevant to FutureBasic.