Section 8.2

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. finally ne dépend pas de l’erreur.
  • Remplacez l’accès au tableau par 10 / doses avec doses à zéro, et le catch par DivideByZeroError : l’autre erreur du cours, attrapée pareil.
  • Écrivez un return dans le finally d’une méthode qui rend un int, et lisez le refus.
  • Empilez les deux catch — IndexOutOfRangeError puis DivideByZeroError — sur un try qui ne peut lever que la seconde : le premier ne voit rien passer.