Documentation channel: current development main at compiler checkpoint 1d7e15e. The latest tagged release is v0.0.3; pages identify APIs that are not yet released.

Errors

Checked error types are part of a function signature. A function either handles a checked error or declares that it may propagate it.

Use the checked-error types exposed by the API that can fail, such as HttpError, SqliteError, NetworkError, and FilesystemError, or declare an application-specific error with error Name { ... }. strut api --json lists the contracts for built-in APIs.

Custom checked errors

A custom error is nominal: only values declared with error can appear in checked-error contracts, throw, and typed catches. The first runtime model standardizes optional message and code payload fields; other fields remain useful to the declaring type but are not yet preserved by a caught runtime payload.

error ValidationError {
    string message;
    int code;
}

function validate(int value) -> int : ValidationError {
    if (value < 0) {
        throw ValidationError { message: "negative value", code: 42 };
    }
    return value;
}

function main() -> int {
    try {
        validate(-1);
    } catch (ValidationError err) {
        println(err.message);
        println(err.code);
    }
    return 0;
}

Across a module boundary

Error declarations and checked-error contracts remain nominal when imported from another source module. Here module-error.h declares ModuleError and module_failure; this calling source is compiled and run by the documentation suite.

include "module-error.h";

function main() -> int {
    try {
        module_failure();
    } catch (ModuleError err) {
        println(err.message);
        println(err.code);
    }
    return 0;
}

Declare checked errors

function load(string path) -> Config : IOError {
    // ...
}

Declare multiple errors

function load(string path) -> Config : (IOError, ParseError) {
    // ...
}

Throw

throw IOError("could not read configuration");

Try and typed catch

try {
    config := load("config.json");
} catch (IOError err) {
    err << "I/O failure" << endl;
} catch (ParseError err) {
    err << "invalid configuration" << endl;
}

Catch all

try {
    risky();
} catch {
    err << "operation failed" << endl;
}

Strut currently favours explicit handling or explicit propagation in the signature rather than adding a separate terse propagation token before its behaviour is justified by real code.