107 Runtime Failures and Exceptions

Runtime exceptions are failures explicitly specified by a language operation or reported through a runtime or external-operation contract. A static error is different: it is reported before the program runs, is never raised by executing the program, and cannot be caught.

The standard library type Exception is the common supertype of Predica runtime exceptions. A catch clause binds the thrown exception to a local variable whose scope is the catch block.

Catchable Failures

The following failures are runtime exceptions:

  • a transaction commit whose final state violates constraints (in configurations where that is enforced);
  • a dynamic-mode type failure discovered while executing;
  • a procedure or external operation that reports a runtime failure through the Predica runtime.

By contrast, static type check failures, static cardinality constraint check failures, name-resolution failures, illegal update targets, and invalid transaction shapes that can be rejected statically are static errors. They are not exceptions and cannot be caught with try.

A possible read of an uninitialised location is likewise a static error rather than a runtime exception; see Uninitialised Locations.

Constraint violations are not specified as runtime exceptions; see Constraint-Violating Updates.

Reaching an unreachable; statement is also not a catchable exception. It makes the program illegal by violating a programmer assertion and the language does not prescribe the subsequent execution behaviour, as specified in Unreachable.

Try Statements

A try statement executes its try block. If no runtime exception is raised, the catch clauses are skipped. If a runtime exception is raised, normal execution of the try block stops and control transfers to the first catch clause whose type matches the exception. If no catch clause matches, the exception propagates to the enclosing statement context.

The catch type may be Exception or a subtype of Exception. If several catch clauses are written, they are tested in source order and the first matching catch block is executed.

A try statement is statement syntax. It may appear in top-level scripts, procedures, and block-bodied function bodies. In a block-bodied function, try does not by itself make the function impure; the try block and catch blocks must still satisfy the ordinary function-purity rules.

Predica does not currently define a general source-level throw statement. Runtime exceptions are raised by specified language operations, by transaction commit, or by external operations that report failure through the Predica runtime.

Ownership transfer is not reversed by exception propagation. If ^s transfers a value into a call that raises an exception, s remains uninitialised. An exclusive reference granted with &s ends when the call exits exceptionally, just as it does on a normal return. See Parameter Access and Ownership.