Option and Result Types: Error Handling
18.1 Concepts
A value of type T or none A value of type T or an error (IError) Result without a value Success or an error
V has no exceptions and no null. Errors are values that must be handled.
18.2 Results (!T)
import os
fn read_config(path string) !string {
if !os.exists(path) {
return error('config not found: ${path}')
}
return os.read_file(path)! // `!` propagates the error to the caller
}
fn main() {
// 1. or block: handle the error (err is available implicitly)
cfg := read_config('app.conf') or {
eprintln('Error: ${err}')
'default config' // fallback value (last expression)
}
println(cfg)
// 2. Propagate with `!` (the enclosing fn must return a result type)
// 3. panic on error
data := read_config('x') or { panic(err) }
_ = data
// 4. if guard
if c := read_config('app.conf') {
println(c)
} else {
println('failed: ${err}')
}
}18.3 Options (?T)
struct User { name string }
fn find_user(id int) ?User {
if id == 1 { return User{'Ana'} }
return none
}
fn main() {
u := find_user(2) or { User{'guest'} }
println(u.name)
if user := find_user(1) { println(user.name) }
name := find_user(1)?.name // `?` propagation (inside fns returning an option)
_ = name
}18.4 Custom Error Types
error('msg'), error_with_code('msg', 42), err.msg(), err.code().
struct NotFoundError {
Error // embed the base Error to implement IError
resource string
}
fn (e NotFoundError) msg() string { return '${e.resource} not found' }
fn (e NotFoundError) code() int { return 404 }
fn get(resource string) !string {
return NotFoundError{resource: resource}
}
fn main() {
get('user') or {
if err is NotFoundError {
println('Custom: ${err.msg()} (code ${err.code()})')
} else {
println(err)
}
return
}
}18.5 Option/Result Fields and Variables
struct Settings {
theme ?string // option field
}
s := Settings{}
println(s.theme or { 'light' })
mut maybe := ?int(none)
maybe = 518.6 Panics and Recovery
panic('msg') aborts with a stack trace (unrecoverable, for bugs).
assert cond, 'message' panics in debug and test builds.
There's no recover mechanism. Design with results instead.
Array index out of bounds and division by zero panic. arr[i] or { } gives safe access.