Functions signal problems by raising errors, and callers catch them with try/except blocks. When you want errors as values instead of exceptions, there is also Result[T, E] with Ok and Err variants.
def divide(a: Int, b: Int) -> Int {
if b == 0 {
raise ValueError("division by zero")
}
return a // b
}
try {
let result = divide(10, 0)
} except ValueError as e {
print("Bad value")
} except Error as e {
print("Some other error")
} finally {
print("Always runs")
}
except Error: is the broadest catch. Bare except: is not supported. You can raise a string directly: raise "message" wraps it in RuntimeError.
| Type | Use case |
|---|---|
Error | Base of all Vary errors |
RuntimeError | General runtime errors |
TypeError | Type mismatches |
ValueError | Invalid values |
IOError | I/O failures |
KeyError | Missing dictionary keys |
IndexError | Out-of-bounds access |
ContractViolation | Failed precondition or postcondition |
ProcessError | Subprocess execution failure (not found, permission denied, timeout) |
TimeoutError | Task group exceeded its timeout |
Result[T, E] represents success or failure without exceptions:
def divide(a: Int, b: Int) -> Result[Int, Str] {
if b == 0 {
return Err("division by zero")
}
return Ok(a // b)
}
let r = divide(10, 3)
assert r.is_ok()
assert r.unwrap() == 3
| Method | Returns | Description |
|---|---|---|
.is_ok() | Bool | True if Ok |
.is_err() | Bool | True if Err |
.unwrap() | T | Unwrap Ok value (panics on Err) |
.unwrap_err() | E | Unwrap Err value (panics on Ok) |
.unwrap_or(default) | T | Unwrap Ok, or return default |
Match on Result with case Ok(value) and case Err(error).
? operatorThe ? postfix operator unwraps Ok or returns Err early:
def process() -> Result[None, FsError] {
let wp = WritePath.of("/tmp/out.txt")?
let _w = fs.write_text(wp, "hello")?
return Ok(None)
}
The enclosing function must return a Result with the same error type.
?else return operatorWhen unwrapping a Result or optional, ?else return provides a default value and exits the function early if the unwrap fails:
def get_name(id: Int) -> Str {
let user = find_user(id) ?else return "unknown"
return user.name
}
This is useful when the enclosing function does not return a Result and you want a fallback instead of propagating the error.