Errors

All Tenet operations either:

  1. Return a valid representation of a Tenet value.
  2. Signal a failure has occurred.

The Tenet language does not have a specific error type. User-defined errors in Tenet are represented as ordinary values, typically through unions.

If the implementation can’t faithfully carry out a request, it must signal a failure.

User-defined errors

A Tenet function presents errors to the target as a regular value. For example, ok~33 might indicate a calculation succeeded with a value of 33 and #div_zero might indicate an attempted division by zero.

Partial functions and operators

Certain operations are partial over their inputs; that is, not all inputs return a value. When an input is outside the function’s domain, the processing must be avoided. The mechanism to do this is syntactically similar to exception handling in other languages.

try {
    ... before ...
    x := a // b
    ... after okay ...
} catch Div_By_Zero {
    x := 3
    ... after catch ...
}

The distinction, however, is that in Tenet, partial functions are never invoked with inputs outside their domain. Rather, the code is translated to:

... before ...
if b != 0 {
   x := a // b
   ... after okay ...
} else {
   x := 3
   ... after catch ...
}

Ideally, the specification would describe a robust algorithm and dependent type system to prove that user-defined functions are total and avoid the need for try / catch. It is a deficiency in this specification that it does not, but the specification must be revised before conformant implementations may do so.

Exceptions

To allow the user to manage partial functions, various types of exceptions may be raised.

Failures

By design, the language ensures user-defined functions are total and convergent. However, execution of the function may fail for a variety of reasons even if the function is well defined; there is no software solution to the power being shut off.

Failures can not be caught by a Tenet catch statement. When possible, failures should use the host language’s facility for reporting errors.

There is no hard and fast rule for how failures should be signaled. Whatever fits with the host langauge conventions should be acceptable.

Representation failure

A representation failure indicates that a value is a valid Tenet value, but can not be faithfully represented by the implementation, or may not be able to be translated to a native value.

The implementation should never continue processing an unrepresentable value or return an incorrect value; it should abort processing and signal failure.

It is permitted to rewrite an expression such that the intermediate values are never or less often unrepresentable, provided the end result is correct.

If certain parts of a complex value can’t be represented, an option is to fail on access to that value. For example, if a record (a: BIG, b: "blue") is returned by an operation, and a is never accessed at runtime, no failure is required to be signaled.

Decoding failure

An decoding failure indicates that the host application attempted to construct a Tenet value from data that can not be decoded.

External failure

An external failure is one that is generally beyond the control of the implementation. Examples include out of memory conditions, IO failures, thread interruption, etc.

Compilation failure

A compilation failure indicates the Tenet source can’t compile.

A static interface presents all compilation failures at build time.

Warnings

Compilation warnings indicate a potential logic error and thus, unless specifically overridden, should fail compilation.

Expensive operation warning

Operations that may be unexpectedly expensive should raise a warning.

Expensive operations include:

Parse failure

A parse failure indicates the Tenet source can’t be parsed.

Typing failure

A typing failure indicates the type inference engine detected contradictory types, or could not resolve types to a single type.

A typing failure must be signalled if an implementation determines that a value of an invalid type is passed to a function, or if a function returns a value contrary to its declared type.