Skip to content

Error Handling V2

Daniel edited this page Feb 15, 2019 · 1 revision

Table of Contents

Error Categories

User Errors

Valid Tengo values of Error type, explicitly created using error expression.

Expected Run-Time Errors

Most of these run-time errors are due to Tengo's dynamic typing: value types are not known at the compile-time.

  • Type errors:
    • unsupported binary operators (lhs-op-rhs)
    • non-iterable types
    • non-indexable types
    • non-index-assingable types
    • invalid index value types
    • non-callable types
  • Others:
    • invalid slicing indexes
    • function call arguments count mismatch

Critical Run-Time Errors

They're serious enough to be handled separately/differently.

  • Stack overflow/underflow
  • Nil pointer or out-of-bounds indexes on VM globals

Current

Convention is the function return an Error value in case of error instead of real return value. It's straightforward but verbose (like Go 1's if err != nil), and, does not work for run-time errors.

res := some_func()
if is_error(res) {
    res.value // <- underlying error value
}

// shorter version
if res := some_func(); is_error(res) {
}

Proposal 1

A little bit similar to Go 2's check-handle syntax: function being the unit scope of error handling

myfunc := func() {
    // handle statement will be executed for both run-time and user errors
    handle err {
        // do some error handling
        err.value      // underlying error value
        err.is_runtime // if it's run-time error

        // may override return value
        return something_else
    }

    // run-time error
    a := non_indexable_value["abc"]

    // user error via 'check' expression
    check may_return_error() // or check(may_return_error()) ??
}

Notes:

  • Similar to future Go syntax
  • Handle both run-time and user errors in one place. But is it really a good idea?
  • Less straightforward control flow
  • Should it propagate to outer function scope? Maybe not?
  • 'check' expression without 'handle' statement in the same function: compile error
  • 'check' expression before 'handle' statement: compile error (lexical)
  • Should allow multiple 'handle' statements in one function? (Go 2 does)
  • Edge cases: what if 'handle' statement does some crazy things e.g. imports modules, self-recursion.

Implementation:

  • Compiler compiles the body of 'handle' statement as if it's another function defined in the same function scope.
  • Compiled 'handle' function is associated with the main function.
  • VM invokes the associated 'handle' function in case of run-time/user errors in the function.