# Exception

The statement

>     TRY
>       S
>     CATCH T1(t1):
>       C1
>     CATCH T2(t2):
>       C2
>     END;

is roughly equivalent to

1. Push exception handler for this TRY block (PushContext).

2. Evaluate S, followed by PopContext. If there are any RETURN or EXIT statements within S that would cause control flow to leave the TRY statement, then they also do an implicit PopContext as part of the non-local exit.

3. If an exception is raised during S, then do

   >     Exception.PopContext;
   >     temp := Exception.Current();
   >     WITH temp: T1 DO
   >       t1 := temp;
   >       C1;
   >     | temp: T2 DO
   >       t2 := temp;
   >       C2;
   >     ELSE
   >       Exception.ActivateContext;
   >     END;
   >     Exception.Clear;

An exception is raised by calling the predefined procedure RAISE with an instance of Exception. This passes control to the nearest CATCH clause whose type is an extension of the raised exception, if such a clause exist. Otherwise, the exception is written to stderr and the program is aborted.

Within a CATCH, the optional name given in parenthesis refers to the current exception that triggered the CACTH. Its type is the one from the CATCH clause. The variable is read-only.

An exception E that is an extension of Checked must either be caught within a procedure, or the procedure must declare that it may pass an exception of type E up to its caller. For example,

>     PROCEDURE P() RAISES E;

declares that evaluation of ``P`' may raise an exception of type E, or an extension thereof.

Within the module body no exceptions can be passed up, because there is no caller. As a consequence, any checked exception that is not caught explicity is written to stderr and aborts the program.

Exceptions derived from Unchecked can always be raised, independent of the context. They do not need to be enclosed in a TRY statement, nor are they required to be listed in a procedure's RAISES list.

Note: A TRY block is mapped to C's ``setjmp()`' function by oo2c. The amount of data stored by this function depends on the target architecture and may differ by a factor of ten or more. For example, on a ``ix86`' processor, only 72 bytes are stored, while on a ``PPC`' this is 768 bytes. As a consequence, the work done within a TRY should be large enough to amortize the costs of the TRY for all possible targets.

### Import List

        Object
        Object

Class List
Checked | Exceptions of this kind must be explicitly dealt with, either by catching them or declaring to pass them on.
Context | Use by the run-time system to store an execution context for later (re)use.
Exception |
ParseError |
ThreadState | Holds thread local state for the exception module.
Unchecked | Exceptions derived from this class can be raised anytime, without restrictions.

Class Summary: Checked [Detail]

      +---Exception.Exception
           |
           +--Exception.Checked

Exceptions of this kind must be explicitly dealt with, either by catching them or declaring to pass them on. The compiler enforces this restriction.

Inherited Methods
From Exception.Exception: GetMessage, INIT, Name, WriteBacktrace

Class Summary: Context [Detail]

      +--Exception.Context

Use by the run-time system to store an execution context for later (re)use.

Class Summary: Exception [Detail]

      +--Exception.Exception

Constructor Summary
Current(): Exception Return the pointer to the currently active exception.
Method Summary
GetMessage(): STRING Return the message string describing the exception e.
INIT(STRING) Initialize exception e and set msg as its message.
Name(): String8 Return the name of the execption's type as ``module.typename`'.
WriteBacktrace() If available, write the top-most entries of the call stack to stderr.

Class Summary: ParseError [Detail]

      +---Exception.Exception
           |
           +--Exception.ParseError

Field Summary
offset-: LONGINT The offset relative to the beginning of the parsed text where the error was found.
Method Summary
INIT(STRING, LONGINT) Initialize exception e and set msg as its message.
Inherited Methods
From Exception.Exception: GetMessage, INIT, Name, WriteBacktrace

Class Summary: ThreadState [Detail]

      +--Exception.ThreadState

Holds thread local state for the exception module.

Constructor Summary
InitThreadState(VAR ThreadState)

Class Summary: Unchecked [Detail]

      +---Exception.Exception
           |
           +--Exception.Unchecked

Exceptions derived from this class can be raised anytime, without restrictions. In particular, they do not need to be declared in a procedure's RAISES list if the procedure may raise such an exception.

Inherited Methods
From Exception.Exception: GetMessage, INIT, Name, WriteBacktrace

Procedure Summary
Abort(Exception) Write data of exception e to stderr and abort program.
ActivateContext() Activate the execution context on the top of the exception handler stack.
Clear() Set the current exception marker to NIL.
FatalError(STRING) Raise an exception with message msg and abort program.
PopContext(LONGINT) Remove n entries from the top of exception handler stack.
PushContext(VAR Context, PTR) Push context on the stack of exception handlers, and make it point to the execution context jmpbuf.
Raise(Exception) Raise exception e.

Variable Summary
GetThreadState: (): ThreadStatePtr Return a pointer to the per-thread data area for exception state.

Class Detail: Checked

Class Detail: Context

Class Detail: Exception

Constructor Detail

### Current

    PROCEDURE Current(): Exception

> Return the pointer to the currently active exception. This is NIL if no exception has been raised, or when a CATCH clause has been completed successfully for the last exception. Within a CATCH block that includes a name in parenthesis, the name identifies a predefined read-only variable holding the same pointer value.

> Note: Within a CATCH block, this function's result becomes undefined at the start of the first TRY statement nested in the CATCH. Catching into a name defines the value over the whole CATCH block.

Method Detail

### GetMessage

    PROCEDURE (e: Exception) GetMessage(): STRING

> Return the message string describing the exception e.

### INIT

    PROCEDURE (e: Exception) INIT(msg: STRING)

> Initialize exception e and set msg as its message. msg may be NIL, but in this case Exception.GetMessage must be redefined to provide a non-NIL message.

> Pre-condition: e is not NIL.

### Name

    PROCEDURE (e: Exception) Name(): String8

> Return the name of the execption's type as ``module.typename`'.

### WriteBacktrace

    PROCEDURE (e: Exception) WriteBacktrace()

> If available, write the top-most entries of the call stack to stderr. This function uses the GNU function ``backtrace_symbols()`' to produce its output. Please see the documentation of GNU libc for more information on how to make function names available to the program. The tool ``oobacktrace`' may also be able to add function names to the output.

Class Detail: ParseError

Field Detail

### offset

    FIELD offset-: LONGINT

> The offset relative to the beginning of the parsed text where the error was found. If this information is not available, then this field is ``-1`'.

Method Detail

### INIT

    PROCEDURE (e: ParseError) INIT(msg: STRING;
                   offset: LONGINT)

> Initialize exception e and set msg as its message. msg may be NIL, but in this case Exception.GetMessage must be redefined to provide a non-NIL message.

> Pre-condition: e is not NIL.

> [Description inherited from INIT]

> Redefines: INIT

Class Detail: ThreadState

Constructor Detail

### InitThreadState

    PROCEDURE InitThreadState(VAR ts: ThreadState)

Class Detail: Unchecked

Procedure Detail

### Abort

    PROCEDURE Abort(e: Exception)

> Write data of exception e to stderr and abort program.

### ActivateContext

    PROCEDURE ActivateContext()

> Activate the execution context on the top of the exception handler stack. If the stack is empty, a message with details of the current exception is written to stderr, and the program is aborted. This procedure should never be called directly.

### Clear

    PROCEDURE Clear()

> Set the current exception marker to NIL. This procedure is called at the very end of a CATCH block. It should never be called directly.

> Note: This procedure does not restore the value of Current to that of the beginning of a TRY statement. That is, after a TRY Current is NIL if an exception was raised.

### FatalError

    PROCEDURE FatalError(msg: STRING)

> Raise an exception with message msg and abort program.

### PopContext

    PROCEDURE PopContext(n: LONGINT)

> Remove n entries from the top of exception handler stack. This procedure should never be called directly.

> Pre-condition: ``n >= 1`'.

### PushContext

    PROCEDURE PushContext(VAR context: Context;
                          jmpbuf: PTR)

> Push context on the stack of exception handlers, and make it point to the execution context jmpbuf. This procedure should never be called directly.

### Raise

    PROCEDURE Raise(e: Exception)
      RAISES Exception;

> Raise exception e. On systems that support it, the first time this procedure is called with a given exception it stores the first few entries of the call stack. This procedure is the implementation of the predefined procedure RAISE.

> Pre-condition: e is not NIL.

Variable Detail

### GetThreadState

    VAR GetThreadState: (): ThreadStatePtr

> Return a pointer to the per-thread data area for exception state. If the program uses threading, then this function returns a pointer to thread local storage.