Handling exceptions
Whether an exception is thrown by the runtime system or by
a THROW statement in an application script, you
handle the exception by catching it. This is done by surrounding
the set of application logic that throws the exception with code
that indicates how the exception is to be dealt with.
TRY-CATCH-FINALLY block
To handle an exception in PowerScript, you must include some
set of your application logic inside a try-catch block. A try-catch
block begins with a TRY clause and ends with
the END TRY statement. It must also contain either
a CATCH clause or a FINALLY clause.
A try-catch block normally contains a FINALLY clause
for error condition cleanup. In between the TRY and FINALLY clauses
you can add any number of CATCH clauses.
CATCH clauses are not obligatory, but if
you do include them you must follow each CATCH statement
with a variable declaration. In addition to following all of the
usual rules for local variable declarations inside a script, the
variable being defined must derive from the Throwable system type.
You can add a TRY-CATCH-FINALLY, TRY-CATCH,
or TRY-FINALLY block using the Script view Paste
Special feature for PowerScript statements. If you select
the Statement Templates check box on the AutoScript tab of the Design Options
dialog box, you can also use the AutoScript feature to insert these block
structures.
Example
Example catching a system error
This is an example of a TRY-CATCH-FINALLY block
that catches a system error when an arccosine argument,
entered by the application user (in a SingleLineEdit) is not in
the required range. If you do not catch this error, the application
goes to the system error event, and eventually terminates:
1 |
Double ld_num<br>ld_num = Double (sle_1.text)<br>TRY<br>   sle_2.text = string (acos (ld_num))<br>CATCH (runtimeerror er)   <br>   MessageBox("Runtime Error", er.GetMessage())<br>FINALLY   <br>   // Add cleanup code here   <br>   of_cleanup()   <br>   Return<br>END TRY   <br>MessageBox("After", "We are finished.") |
The system runtime error message might be confusing to the
end user, so for production purposes, it would be better to catch
a user-defined exception—see the example in “Creating user-defined exception
types”—and
set the message to something more understandable.
The TRY reserved word signals the start
of a block of statements to be executed and can include more than
one CATCH clause. If the execution of code in
the TRY block causes an exception to be thrown,
then the exception is handled by the first CATCH clause
whose variable can be assigned the value of the exception thrown.
The variable declaration after a CATCH statement
indicates the type of exception being handled (a system runtime
error, in this case).
CATCH order
It is important to order your CATCH clauses
in such a way that one clause does not hide another. This would
occur if the first CATCH clause catches an exception
of type Exception and a subsequent CATCH clause
catches a descendant of Exception. Since they are processed in order,
any exception thrown that is a descendant of Exception would be
handled by the first CATCH clause and never by
the second. The PowerScript compiler can detect this condition and
signals an error if found.
If an exception is not dealt with in any of the CATCH clauses,
it is thrown up the call stack for handling by other exception handlers
(nested try-catch blocks) or by the system error event. But before
the exception is thrown up the stack, the FINALLY clause
is executed.
FINALLY clause
The FINALLY clause is generally used to
clean up after execution of a TRY or CATCH clause.
The code in the FINALLY clause is guaranteed
to execute if any portion of the try-catch block is executed, regardless
of how the code in the try–catch block completes.
If no exceptions occur, the TRY clause
completes, followed by the execution of the statements contained
in the FINALLY clause. Then execution continues
on the line following the END TRY statement.
In cases where there are no CATCH clauses
but only a FINALLY clause, the code in the FINALLY clause
is executed even if a return is encountered or an exception is thrown
in the TRY clause.
If an exception occurs within the context of the TRY clause
and an applicable CATCH clause exists, the CATCH clause
is executed, followed by the FINALLY clause.
But even if no CATCH clause is applicable to
the exception thrown, the FINALLY clause still
executes before the exception is thrown up the call stack.
If an exception or a return is encountered within a CATCH clause,
the FINALLY clause is executed before execution
is transferred to the new location.
Do not use RETURN statements in the FINALLY clause
of a TRY–CATCH block. This
can prevent the exception from being caught by its invoker.