The language's errors, and finally
Catching what the language throws — and guaranteeing a cleanup, whatever happens.
The course has already had you provoke two errors defenceless: the index out of bounds in 6.1,
the integer division by zero in 2.3. The language throws them through the very same mechanism
as you — archetypes, supplied without an import.
@entry(start)
object MyProgram {
start() {
var readings := [12, 19, 7];
try {
Console.print(text: $"{readings[5]}");
} catch (raised: IndexOutOfRangeError) {
Console.print(text: $"refused: {raised.message}");
} finally {
Console.print(text: "the cauldron is rinsed");
}
Console.print(text: "the program goes on");
}
}
The language’s errors are archetypes like yours
IndexOutOfRangeError, DivideByZeroError, OverflowError: each carries a message, and a
catch takes them like your own. The 6.1 program that fell on readings[5] now knows how to
survive — “the program goes on”.
var doses := 0;
try {
Console.print(text: $"{10 / doses}");
} catch (raised: DivideByZeroError) {
Console.print(text: $"caught: {raised.message}");
}
Several catches stack
After one try, the catches are written in a row and tried in writing order — the first
whose type matches receives the error, the others see nothing. An error none of them takes
keeps climbing.
finally — whatever happens
} finally {
Console.print(text: "the cauldron is rinsed");
}
The finally block runs in every case: error caught, no error raised, and even an error
that keeps climbing. It is where cleanup belongs — closing, rinsing, giving back — the things
that must depend on nothing.
One rule applies inside it, and the compiler holds it:
error[D007]: 'return' is forbidden inside a 'finally': it would silently overwrite
what the 'try' returns (see docs/decisions.md, 'Gestion des erreurs')
A return inside a finally would silently overwrite what the try returns — the trap
exists elsewhere, Archon closes it.
Your turn
- Set the index to 1: no error anymore — and “the cauldron is rinsed” still prints.
finallydoes not depend on the error. - Replace the array access with
10 / doseswheredosesis zero, and thecatchwithDivideByZeroError: the course’s other error, caught the same way. - Write a
returninside thefinallyof a method returning anint, and read the refusal. - Stack both
catches —IndexOutOfRangeErrorthenDivideByZeroError— on atrythat can only raise the second: the first sees nothing pass.