Les erreurs du langage, et finally
Attraper ce que le langage lance — et garantir un nettoyage, quoi qu'il arrive.
Le cours vous a déjà fait provoquer deux erreurs sans défense : le rang hors des bornes en 6.1,
la division entière par zéro en 2.3. Le langage les lance avec le même mécanisme que vous — des
archetypes, fournis sans import.
@entry(demarrer)
object MonProgramme {
demarrer() {
var mesures := [12, 19, 7];
try {
Console.print(text: $"{mesures[5]}");
} catch (erreur: IndexOutOfRangeError) {
Console.print(text: $"refusé : {erreur.message}");
} finally {
Console.print(text: "le chaudron est rincé");
}
Console.print(text: "le programme continue");
}
}
Les erreurs du langage sont des archetypes comme les vôtres
IndexOutOfRangeError, DivideByZeroError, OverflowError : chacune porte un message, et
un catch les attrape comme les vôtres. Le programme de la 6.1 qui tombait sur mesures[5]
sait maintenant survivre — « le programme continue ».
var doses := 0;
try {
Console.print(text: $"{10 / doses}");
} catch (erreur: DivideByZeroError) {
Console.print(text: $"attrapée : {erreur.message}");
}
Plusieurs catch s’empilent
Après un même try, les catch s’écrivent à la suite et sont essayés dans l’ordre
d’écriture — le premier dont le type correspond reçoit l’erreur, les autres ne voient rien.
Une erreur qu’aucun n’attrape continue de remonter.
finally — quoi qu’il arrive
} finally {
Console.print(text: "le chaudron est rincé");
}
Le bloc finally s’exécute dans tous les cas : erreur attrapée, erreur non levée, et même
erreur qui continue de remonter. C’est la place du nettoyage — fermer, rincer, rendre — qui ne
doit dépendre de rien.
Une règle s’y applique, et le compilateur la tient :
error[D007]: 'return' is forbidden inside a 'finally': it would silently overwrite
what the 'try' returns (see docs/decisions.md, 'Gestion des erreurs')
Un return dans un finally écraserait en silence ce que le try rend — le piège existe
ailleurs, Archon le ferme.
À vous
- Mettez le rang à 1 : plus d’erreur — et « le chaudron est rincé » s’affiche quand même.
finallyne dépend pas de l’erreur. - Remplacez l’accès au tableau par
10 / dosesavecdosesà zéro, et lecatchparDivideByZeroError: l’autre erreur du cours, attrapée pareil. - Écrivez un
returndans lefinallyd’une méthode qui rend unint, et lisez le refus. - Empilez les deux
catch—IndexOutOfRangeErrorpuisDivideByZeroError— sur untryqui ne peut lever que la seconde : le premier ne voit rien passer.