Lesson 4: Failures as part of the contract
Treat errors as data — Option, Result, and the ? operator.
Goal
In one sentence: return and propagate errors explicitly and scannably.
Code
public func fetchBalance(account: ref Account): Result<int, str> {
if account.active == false {
return Result.Err("account disabled")
}
return Result.Ok(account.balance)
}
The type Result<int, str> says the function either returns an int (Result.Ok(...)) or an error message (Result.Err(...)). No hidden exceptions behind the scenes.
Propagating with ?
public func summary(account: ref Account): Result<str, str> {
let balance = fetchBalance(account)?
return Result.Ok("Balance: " + balance)
}
The ? shortens propagation: on Err, the whole function returns that error; on Ok, you get the value.
Try it
Remove the ? from fetchBalance(account) and watch the compiler ask you to handle the Result explicitly. It will not let an error slip through without you deciding what to do.
Option<T> works the same way: Option.Some(...) or Option.None, no null. Combine Option and Result to model “may not exist” and “may fail” as distinct things.
Errors as values keep the error flow visible in the code itself — you can see exactly where an error might arise.