Exception Groups
Exception groups define a named set of exception types. A catch arm matching a group name expands to match all members.
Declaration
exception NotFound(path: string)
exception PermDenied(path: string, code: i64)
exception group IOError = NotFound | PermDenied
Groups are declared with exception group Name = Member1 | Member2 | .... Each member must be a previously declared exception. The export modifier makes the group visible to importers.
Structured Exceptions
Individual exceptions carry typed fields – not pre-formatted strings. This enables both fine-grained and coarse-grained error handling:
exception UnexpectedToken(expected: string, got: string, span: Span)
exception MissingMain
exception group ParseError = UnexpectedToken | MissingMain
Zero-field exceptions (like MissingMain) omit parentheses in both declaration and pattern matching.
Catching Groups
Catching a group name expands to match every member:
try
parse(tokens: tokens)
catch
| ParseError ->
// catches both UnexpectedToken and MissingMain
Console.eprintln(val: "parse failed")
end
This is syntactic sugar – the compiler expands | ParseError -> into one arm per member.
Catching Specific Exceptions
For precise handling, match individual exception types and destructure their fields:
try
compile(src: src)
catch
| UnexpectedToken(expected: e, got: g, span: sp) ->
Console.eprintln(val: "expected " ++ e ++ ", got " ++ g)
| TypeMismatch(func_name: f, detail: d, span: sp) ->
Console.eprintln(val: "in " ++ f ++ ": " ++ d)
| MissingMain ->
Console.eprintln(val: "no main function")
end
Specific arms and group arms can be mixed. The compiler checks each arm independently.
Multi-Arm Catch
The catch clause supports two forms:
// Legacy: single variable binding
try body catch e -> handle(e: e) end
// Multi-arm: pattern matching on exception constructors
try
body
catch
| NotFound(msg: m) -> handle_missing(m: m)
| PermDenied(msg: m) -> handle_perm(m: m)
| IOError -> handle_generic()
end
Multi-arm catch desugars to catch __exn -> match __exn do ... end during compilation.
Group Composition
Groups reference individual exceptions, not other groups. To create a “super-group” spanning multiple phases, list all members directly:
exception group CompileError =
UnexpectedToken | MissingMain
| TypeMismatch
| SymbolNotFound
Groups are expanded at catch sites – there is no hierarchical nesting at runtime.
See also: Checked Exceptions and Capabilities, Syntax