on exception Instruction

The on exception instruction arms an exception handler.

Syntax

The syntax of the on exception instruction is:

on exception-class do method-call-expression [global];

The exception-class identifier is the Exception class or one of its subclasses. Use the optional global system variable to arm a global exception handler. As a global exception handler is not associated with a specific method, it is always armed until it is explicitly disarmed.

A local exception handler is automatically disarmed when the method that armed it returns.

Each process may have up to 128 global exception handlers armed at any one time. There is no JADE‑imposed restriction on the number of non-global exception handlers that may be armed at any time by any one process.

See also the "Arming Exception Handlers" subsection.

Description

Using the on exception instruction to arm an exception handler causes the specified method to be invoked when an exception of a specified exception class is raised.

Use null in the method-call-expression identifier to disarm an exception handler (using the optional global system variable to disarm a global exception handler).

The following syntax disarms an exception handler.

on exception-class do null [global];

The signature of the exception handler method must be of the following form.

Signature    method-name(e: Exception-class; [other-optional-parameters]): Integer;

In this signature, the e parameter references the exception object created and passed when the exception was raised.

You can optionally specify other parameters when you are creating or arming a method handler to suit your requirements but you must specify the parameter that refers to the exception object as the first parameter. (See also the "Arming Exception Handlers" subsection.) The exception handler would normally use information saved in the Exception class object to decide the action to be taken. Within your method, you can use the isKindOf method to determine the class of the exception object.

An exception handler can also have the following signature.

Signature    method-name(exObj: any-exception-class; [other-parameters]): Integer;

In this signature, the exObj parameter indicates that this exception handler handles only exceptions that are instances of the specified exception class or its subclasses. You could specify o and i optional parameters, for example, to indicate the current object and an integer variable, respectively.

In these exception handler method signatures, the e or exObj parameter must be the first parameter that you specify in the exception handler method signature.

The contents of parameter expressions passed to the exception handler method are evaluated as follows.

The return value indicates the action that the system then takes, as shown in the following table.

Return Value Constant Action
0 Ex_Continue Continues execution from the next expression after the expression that caused the exception.
    Use this return mode only in circumstances when you are certain that continuing the code execution will still be correct after ignoring the exception.
    For lock exceptions, use this return mode only if the lock has been successfully retried. If the lock exception occurred while updating, ensure that the transaction has not been aborted by the exception handler before returning Ex_Continue.
1 Ex_Abort_Action Causes the current action to be aborted. The execution stack is stripped back, and in most cases the application reverts to an idle state in which it is waiting for user input or some other Windows event. (For details, see the "Arming Exception Handlers" subsection.)
2 Ex_Resume_Next Passes control back to the method that armed the exception handler. Resumes from the next statement after the evaluation of the method call or expression in which the exception occurred. If there were no messages on the execution stack when the handler was armed, the effect of the Ex_Resume_Next call is identical to that of the Ex_Abort_Action call.
   

You cannot resume from global exception handlers. Using this value for a global exception handler is equivalent to returning the Ex_Abort_Action value.

If an exception occurs during evaluation of a return expression, when the exception handler returns, the executing method is terminated (in accordance with executing a return instruction) and the default value of the return type is returned.

-1 Ex_Pass_Back Passes control back to the prior local exception handler for this type of exception or if a local handler is not found, a global exception handler for this type of exception. If neither a local nor a global handler is found, the default exception handler is invoked on a client. On the server, it passes the exception back to the client node.
    Note that if an exception occurs while executing a server method and no user exception handlers are armed, the default handler is invoked on the server node. This aborts any current transaction on the server and raises a 1242 exception on the client node that invoked the server method execution.

Examples

The following examples show the use of the on exception instruction.

on SystemException do printException(exception);
app.printer.print(folio.detail);
foreach portfolio in app.investor.myPortfolios do
    folio.compName.caption := portfolio.companyName;
    app.printer.print(folio.compDetail);
endforeach;

The exception parameter value is a system variable operand that provides a reference to the exception object when an exception is raised. For more information about arming an exception handler, see Chapter 3, "Exceptions".

The following is an example of a method on a Document class that writes the document to a file. It arms a local exception handler to catch file exceptions.

writeToFile();
vars
    fileSaveDialog : CMDFileSave;
    file           : File;
begin
    on FileException do fileExceptionHandler(exception);
    create fileSaveDialog transient;
    if fileSaveDialog.open = 0 then
        create file transient;
        file.mode     := File.Mode_Output;
        file.fileName := fileSaveDialog.fileName;
        saveToFile(file);
        file.close;
        delete file;
    endif;
epilog
    delete fileSaveDialog;
end;