Recoverable errors
Recoverable errors are part of the current V1 compiler contract.
FOL routines may declare both:
- a success type
- an error type
The current signature form is:
fun load(path: str): int / str = { ... }
This means:
- successful execution yields
int - failure yields
str report exprexits through the routine’s error path
Declaring error-aware routines
Use / ErrorType after the success type:
fun load(path: str): int / str = {
when(path == "") {
case(true) { report "empty path" }
* { return 1 }
}
}
report expr must produce a value compatible with the declared ErrorType.
This is checked by the current compiler. The following is invalid:
fun load(path: str): int / str = {
report 1
}
because 1 is int, while the routine declares str as its error type.
The same rule applies to methods:
typ Parser: rec = {
name: str
}
fun (Parser)parse_err(code: int): str = {
return "bad-input"
}
fun run(tool: Parser, code: int): int / str = {
report tool.parse_err(code)
}
Propagation
Calling an error-aware routine in a plain value position propagates the error upward, but only inside another error-aware routine with a compatible error type.
fun read_code(path: str): int / str = {
when(path == "") {
case(true) { report "missing path" }
* { return 7 }
}
}
fun main(path: str): int / str = {
return read_code(path)
}
This works because main also declares / str.
If the surrounding routine does not declare a compatible error type, the call is rejected during type checking.
Inspecting a recoverable call
check(expr) is the V1 surface for asking whether an error-aware routine call
failed.
It returns bol.
fun read_code(path: str): int / str = {
when(path == "") {
case(true) { report "missing path" }
* { return 7 }
}
}
fun main(path: str): int / str = {
var value: int = read_code(path) || 0
when(check(read_code(path))) {
case(true) { report "read failed" }
* { return value }
}
}
Recovering with ||
expr || fallback is the V1 shorthand for recovering from an error-aware
routine call.
Rules:
- if
exprsucceeds, use its success value - if
exprfails, evaluatefallback fallbackmay:- provide a default value
reportpanic
Examples:
fun read_code(path: str): int / str = {
when(path == "") {
case(true) { report "missing path" }
* { return 7 }
}
}
fun with_default(path: str): int = {
return read_code(path) || 0
}
fun propagate_with_context(path: str): int / str = {
return read_code(path) || report "read failed"
}
fun must_succeed(path: str): int = {
return read_code(path) || panic "read failed"
}
Routine errors are not err[...] shells
Routine call results with / ErrorType are not the same thing as err[...]
shell values.
That distinction is important in the current compiler:
check(expr)andexpr || fallbackwork on error-aware routine calls- postfix
!works on shell values such asopt[...]anderr[...] - postfix
!does not unwrap routine call results declared with/ ErrorType
Examples:
var failure: err[str] = "broken"
var value: str = failure!
This is a shell unwrap.
The following is a different surface:
fun read_code(path: str): int / str = { ... }
Here the call result is a recoverable routine result, not an err[...] shell.
Use propagation, check(...), or || with it.
Current V1 boundary
The current compiler supports:
- declared routine error types with
/ report expr- propagation through compatible routine contexts
check(expr)expr || fallback- lowering of these surfaces into explicit recoverable-error IR
For backend work, the important current V1 runtime distinction is:
- routine recoverable results map to the
fol-runtimerecoverable ABI - shell values such as
opt[...]anderr[...]map to separate shell runtime types - those two categories are intentionally not merged
So a future backend should treat a lowered recoverable routine result as the
runtime recoverable object, not as an err[...] shell and not as a tuple-like
user value.
The current compiler does not yet claim:
- advanced Zig-style success/error capture syntax
- cleanup constructs like
errdefer - backend-specific calling conventions beyond the stable
fol-runtimerecoverable boundary
Those belong to later milestones.