Skip to content

Error Handling

Result Type

Functions that can fail return Result<T, E>:

wyn
fn safe_div(a: int, b: int) -> Result<int, string> {
    if b == 0 { return Err("division by zero") }
    return Ok(a / b)
}

Matching on Results

wyn
match safe_div(10, 3) {
    Ok(v) => println("result: ${v}")
    Err(e) => println("error: ${e}")
}

match as an Expression

match on a Result or Option is also an expression — it produces a value you can assign directly, which is handy for folding both arms into one result:

wyn
fn parse(s: string) -> Result<int, string> {
    if s == "" { return Err("empty") }
    return Ok(42)
}

var r = parse("42")
var msg = match r {
    Ok(v) => v.to_string(),
    Err(e) => e,
}
println(msg)                       // 42

The same works for Option:

wyn
var opt: string? = Some("Wyn")
var name = match opt {
    Some(v) => v,
    None => "anonymous",
}
println(name)                      // Wyn

The ? Operator

Propagate errors automatically with ?. If the expression is Err, the function returns early with that error:

wyn
fn parse(s: string) -> Result<int, string> {
    if s == "42" { return Ok(42) }
    return Err("parse error")
}

fn validate(n: int) -> Result<int, string> {
    if n < 0 { return Err("negative") }
    return Ok(n)
}

fn process(s: string) -> Result<string, string> {
    var n = parse(s)?          // returns Err early if parse fails
    var valid = validate(n)?   // returns Err early if validate fails
    return Ok("processed: ${valid}")
}

Result with String Values

wyn
fn read_config(path: string) -> Result<string, string> {
    if path == "" { return Err("empty path") }
    return Ok("config data")
}

fn load(path: string) -> Result<string, string> {
    var data = read_config(path)?
    return Ok("loaded: ${data}")
}

Option Type

For values that may or may not exist:

wyn
fn find(arr: [int], target: int) -> Option<int> {
    for i in 0..arr.len() {
        if arr[i] == target { return Some(i) }
    }
    return None
}

match find([10, 20, 30], 20) {
    Some(idx) => println("found at index ${idx}")
    None => println("not found")
}

Some / None / Ok / Err for Any Type

The constructors Some(x), None(), Ok(x), and Err(x) work with any payload type, in any context — including a plain variable with a type annotation, not just a function return:

wyn
var name: string? = Some("Wyn")
var missing: string? = None()

var count: int? = Some(42)

Optionals also carry convenience methods, so you don't always need a full match:

wyn
var name: string? = Some("Wyn")

if name.is_some() {
    println("name = ${name.unwrap()}")
}

var count: int? = None()
println(count.unwrap_or(0).to_string())   // 0 — fallback when None

See Also

MIT License — v1.16