Ошибки
Функция, которая может не удаться, возвращает объединение T | E1 | E2. Типы ошибок объявляются с @error — такое значение
нельзя молча проигнорировать. fail e возвращает ошибку, expr? пробрасывает её вызывающему, match разбирает по типу.
@error data NotFound { id: i64 }
@error data Invalid { why: str }
fn find(id: i64) -> str | NotFound {
if id == 1 { return "ann" }
fail NotFound{ id }
}
fn parse(s: str) -> i64 | Invalid {
match s.parseInt() {
i64 n => n
ParseError => fail Invalid{ why: "not a number: {s}" }
}
}
// ? пробрасывает ошибки обеих вызываемых функций; сигнатура перечисляет их все
fn lookup(s: str) -> str | NotFound | Invalid {
let id = parse(s)?
find(id)?
}
fn main() io {
for s in ["1", "2", "x"] {
match lookup(s) {
str name => print("found {name}")
NotFound e => print("no user {e.id}")
Invalid e => print("bad input: {e.why}")
}
}
// цепочка: -> следующий шаг, !> обработчик ошибки
let r = await find(2)
-> it.len()
!> NotFound => 0
print("{r}")
}Вывод
found ann no user 2 bad input: not a number: x 0
- Если в
matchне перечислена возможная ошибка, компилятор сообщает об этом (unhandled-error). - Сетевые вызовы добавляют к результату
NetError(§6.5):Timeout,Unavailableи другие. - Паники (
panic, переполнение, выход за границы) — это не ошибки: они означают баг и завершают задачу (§6.6). mainможет возвращать ошибки:fn main() -> () | Usage | IoError io; необработанная ошибка завершает процесс с кодом 1.