Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Errors

Errors are values. Use raise to stop normal execution with an error and try / catch to recover at a boundary that can make a useful decision.

func divide(a, b) {
    if b == 0 {
        raise ZeroDivisionError.wrap("divide")
    }
    return a / b
}

try {
    print(divide(10, 0))
} catch err {
    print(err.message)
    print(err.is(ZeroDivisionError))
}

The name after catch is local to its catch block. When no error is raised, the catch block is skipped. An unhandled error stops the program and prints a traceback.

Creating and matching errors

Error("message") creates a plain error. Use a sentinel error when callers need to distinguish a particular failure from unrelated errors.

var not_found = Error("not found")

func load_user(id) {
    if id == 0 {
        raise not_found.wrap("loading user")
    }
    return {"id": id}
}

try {
    load_user(0)
} catch err {
    if err.is(not_found) {
        print("choose another user")
    }
}

wrap("context") adds a message while preserving the original error. unwrap() returns the direct cause, and is() tests the complete error chain.

var base = Error("connection failed")
var err = base.wrap("loading profile")
print(err.message)
print(err.unwrap().message)
print(err.is(base))

Error kinds

The runtime uses named error kinds, which can be raised directly or wrapped.

KindTypical cause
TypeErrorAn operation receives an incompatible value
ValueErrorA valid type has an invalid value
IndexError / KeyErrorA missing list index or dictionary key
ZeroDivisionErrorDivision or modulo by zero
AttributeError / NameErrorA missing member or identifier
ImportErrorAn unavailable module
ParseErrorInvalid JSON or other parsed input
IOErrorGeneric file, network, or operating-system failure
NotExistError / ExistError / PermissionErrorA missing, existing, or inaccessible filesystem path
TimeoutError / NetworkErrorA timed-out or other network operation
NotImplementedErrorAn operation the runtime does not implement

Kinds are hierarchical. IndexError and KeyError are LookupErrors; ZeroDivisionError is an ArithmeticError; ParseError is a ValueError. Therefore err.is(LookupError) can handle more than one specific lookup failure.

Wrap errors where you can add useful context. Do not catch an error merely to discard it: either recover with a meaningful alternative, or use raise err to let an outer layer handle it.