9. EXCEPTION HANDLING
A major design criterion for this language is that it contribute toward the reliability of the systems
that it is used to develop. Toward this end, a language facility, called exception handling, is provided
so that a user can gain control and take appropriate action when a runtime error occurs. Both user-defined
and language-defined runtime errors can be handled this way.
There are three parts to exception handling: the definition of an exceptional condition,
called an exception;
the occurrence, or raising, of the exception; and the handling of the raised exception.
Exceptions are either language-defined (see Appendix D) or defined by the user in an exception declaration.
Exception names follow normal scope rules. Exceptions are raised explicitly by the elaboration of a raise or
reraise statement. Language-defined exceptions are also raised automatically when an exceptional condition occurs
during elaboration. The handling of an exception is achieved by the guard statement, which allows the user to gain
control when an exception is raised. The guard statement consists of two parts: a guarded body in which an exception
might be raised; and a set of handlers which can handle exceptions raised in the guarded body. Separate handlers can be
provided for specific exceptions, and a general handler can be provided for all exceptions not handled separately.
When an exception having a handler is raised in the guarded body, the elaboration of the guarded body is terminated
and the body of the handler is elaborated. Elaboration of the guard statement is completed when elaboration of the handler
Guard statements may be nested within one another. When an exception is raised, the guard statement containing
the guarded body in which the exception is raised is examined first. If it does not contain a handler for
that exception, then enclosing guard statements are examined for the appropriate handler, starting with the innermost.
The guard statement selected must meet two criteria; it must contain a handler for this specific exception; and it must
not contain a deferred declaration which contains the raised exception.
If no enclosing guard statement is found before an enclosing deferred declaration is found, for all deferred declarations
except tasks, the search for a handler for the exception continues in the scope containing the invocation of the deferred
unit. In the case of tasks, the task activation is terminated and no further searching occurs.
If the search for a handler causes completion of elaboration of the scope in which the exception name is defined,
the exception name is changed to X_UNHANDLED and the search for the X_UNHANDLED exception begins.
It is possible, within a handler, to reraise the exception which caused the elaboration of the handler. This allows
a local action to be taken before searching resumes for another handler for the same exception.
When efficiency of generated code is more important than the guarantee of reliability, the
suppress pragmat can be used to suppress the raising of exceptions (see Appendix B).