Exception

From Xojo Documentation

Language Keyword

Used to handle RuntimeException errors.

Usage

Exception [[ErrorParameter] [As ErrorType]]

Part Description
ErrorParameter Optional, used to determine the type of runtime exception.
ErrorType Used to 'catch' a particular type of runtime error.

Optional, if used, it must be used with ErrorParameter. If used, the Exception block will handle only that type of runtime error.

Notes

The Exception statement catches runtime exceptions that occur anywhere within the method or event. In most cases using a Try...Catch is better since it allows you to catch exceptions in specific parts of your code.

One or more Exception statements can be inserted after the last "regular" line of code to catch and handle runtime exceptions that may occur anywhere within the method. Local variables that are declared inside an Exception block exist only within the block's scope rather than inside the entire method's scope. This means that multiple Exception statements at the same level can use the same exception variable name.

If a runtime exception occurs in a built application and is not handled, a generic runtime error message box is displayed and the app is quits. Exception statements provide a means of handling the error more gracefully.

Exception statements always appear at the end of a method (not where you think the error might occur) because every line after the Exception line is considered part of the exception block. In the Code Editor, the Exception line has the same level of indentation as the Sub or Function line.

You can use Exception alone if you wish to handle any type of exception in the Exception block, as shown below:

Sub ...

Exception
MessageBox("Something really bad happened, but I don't know what.")

The example shown above is sufficient to prevent the application from quitting, but the message is not very informative because you don't have a clue what type of exception occurred.

The way to determine which type of runtime error occurred is to use ErrorParameter and, in some way, test its type. ErrorParameter can be any of the RuntimeException subclasses.

One way to test ErrorParameter is with an If statement in the Exception block:

Sub ...

Exception err
If err IsA TypeMismatchException Then
MessageBox("Tried to retype an object!")
ElseIf err IsA NilObjectException Then
MessageBox("Tried to access a Nil object!")
End If

The preferred way

Instead of using multiple If statements, you can use multiple Exception statements, each of which handles a different runtime exception type. This is the preferred way to manage exceptions. Note that you can use the same variable name several times, like err in the following example. An exception will be caught only once. As a consequence, a NilObjectException would be caught only by the Exception err as NilObjectException block and not by the last Exception err as RuntimeException (which is not recommended, anyway. See EndException and ThreadEndException).

Sub ...

Exception err As TypeMismatchException
MessageBox("Tried to retype an object!")
Exception err As NilObjectException
MessageBox("Tried to access a Nil object!")
Exception err As RuntimeException // NOT RECOMMENDED
MessageBox("Another exception")

You should not use Return in an exception block as it would prevent the Finally block to execute, if any.

EndException and ThreadEndException

Under some circumstances, an Exception block can catch an EndException or a ThreadEndException. This happens when you use a catch-all exception statement, i.e. "Exception err as RuntimeException" instead of giving a more specific runtime exception class. In such a case, you MUST re-raise the exception to avoid messing up the runtime environment and create some unpredictable problems.

Exception err As RuntimeException // Will catch any exception without discrimination

If err IsA EndException Or err IsA ThreadEndException Then
Raise err // Re-raise the exception
End If

//Continue your code here

Alternative

The Try block is an alternative to the Exception block. Unlike Exception, you can have nested Try statements. If the innermost Try block does not handle the exception, it will be passed to the next block, and so forth. If both Try and Exception statements are used together, the Try block will catch errors prior to the Exception block.

Sample Code

See the examples for the NilObjectException, IllegalCastException, TypeMismatchException, OutOfBoundsException, and StackOverFlowException errors.

See Also

Function, Raise, Sub, Try...Catch statements.