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

Error Handling

TeaLeaf uses the thiserror crate for structured error types.

Error Types

The main error enum:

Error VariantDescription
IoFile I/O error (wraps std::io::Error)
InvalidMagicBinary file doesn’t start with TLBX magic bytes
InvalidVersionUnsupported binary format version
InvalidTypeUnknown type code in binary data
InvalidUtf8String encoding error
UnexpectedTokenParse error – expected one token, got another
UnexpectedEofPremature end of input
UnknownStruct@table references a struct that hasn’t been defined
MissingFieldRequired field not provided in data
ParseErrorGeneric parse error with message
ValueOutOfRangeNumeric value exceeds target type range

Conversion Errors

The ConvertError type is used by FromTeaLeaf:

#![allow(unused)]
fn main() {
pub enum ConvertError {
    MissingField { struct_name: String, field: String },
    TypeMismatch { expected: String, got: String, path: String },
    Nested { path: String, source: Box<ConvertError> },
    Custom(String),
}
}

Handling Errors

Parse Errors

#![allow(unused)]
fn main() {
use tealeaf::TeaLeaf;

match TeaLeaf::parse(input) {
    Ok(doc) => { /* use doc */ },
    Err(e) => {
        eprintln!("Parse error: {}", e);
        // e.g., "Unexpected token: expected ':', got '}' at line 5"
    }
}
}

I/O Errors

#![allow(unused)]
fn main() {
match TeaLeaf::load("nonexistent.tl") {
    Ok(doc) => { /* ... */ },
    Err(e) => {
        // Will be an Io variant wrapping std::io::Error
        eprintln!("Could not load file: {}", e);
    }
}
}

Binary Format Errors

#![allow(unused)]
fn main() {
use tealeaf::Reader;

match Reader::open("corrupted.tlbx") {
    Ok(reader) => { /* ... */ },
    Err(e) => {
        // Could be InvalidMagic, InvalidVersion, etc.
        eprintln!("Binary read error: {}", e);
    }
}
}

Conversion Errors

#![allow(unused)]
fn main() {
use tealeaf::{FromTeaLeaf, Value};

let value = Value::String("not a number".into());
match i32::from_tealeaf_value(&value) {
    Ok(n) => println!("Got: {}", n),
    Err(e) => {
        // ConvertError::TypeMismatch { expected: "Int", got: "String" }
        eprintln!("Conversion failed: {}", e);
    }
}
}

Error Propagation

All errors implement std::error::Error and Display, so they work with ? and anyhow/eyre:

#![allow(unused)]
fn main() {
fn process_file(path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let doc = TeaLeaf::load(path)?;
    let json = doc.to_json()?;
    doc.compile("output.tlbx", true)?;
    Ok(())
}
}

Validation Without Errors

For checking validity without consuming the error:

#![allow(unused)]
fn main() {
let is_valid = TeaLeaf::parse(input).is_ok();
}

The CLI validate command uses this pattern to report validity without stopping on errors.