04 — Errors¶
Mighty has typed recoverable errors and an explicit propagation
operator. Recoverable failures are values of type Result[T, E]. The
sugar T!E desugars to Result[T, E].
The program¶
fn parse(s: Str) -> I32!ParseErr {
Ok(0)
}
fn load(url: Url) -> Page!{NetErr, ParseErr} {
let body = fetch(url)?
parse(body)?
Ok(Page {})
}
What is interesting¶
I32!ParseErris shorthand forResult[I32, ParseErr]. It is the canonical short form per spec §6.3.Page!{NetErr, ParseErr}isResult[Page, NetErr | ParseErr]— a function that may fail with either error type.?propagates errors:fetch(url)?returns early with the wrapped error iffetchreturnedErr, otherwise unwraps toBytes.- Compose error sets explicitly; there is no implicit "anything goes" error type, and there is no exception machinery.
- The final
Ok(Page {})is the success case.Page {}is a struct literal with all defaulted fields.
Try it¶
Type errors you might see¶
? is strict about the enclosing function's return type (amendment
A7):
// MT2010 ? outside Result-returning function
fn returns_unit() -> Unit {
fetch(url)? // can't propagate; fn returns Unit
}
// MT2011 ? error-type mismatch
fn outer() -> Result[I32, NetErr] {
first()? // first() returns Result[I32, IoErr] — err types don't match
Ok(2)
}
To compose a fn that doesn't have any natural Result return, use
Unit!ErrType:
fn process(items: &[I32]) -> Unit!WorkErr {
for item in items {
work(item)? // legal — enclosing fn returns Result[Unit, WorkErr]
}
}
Run mty explain MT2010 for the full Cause/Example/Fix/Spec block.
Next¶
Continue to 05 — Control flow.