OxL Reference

Errors

A function that can fail returns a union T | E1 | E2. Error types are declared with @error: such a value cannot be ignored silently. fail e returns an error, expr? passes it to the caller, match takes it apart by type.

oxl✓ checked in CI
@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}")
}
Output
found ann
no user 2
bad input: not a number: x
0
  • If a match does not list a possible error, the compiler reports it (unhandled-error).
  • Network calls add NetError to the result (§6.5): Timeout, Unavailable and others.
  • Panics (panic, overflow, out-of-range index) are not errors: they mean a bug and end the task (§6.6).
  • main may return errors: fn main() -> () | Usage | IoError io; an unhandled error ends the process with a non-zero exit code.

See also