Gestion des erreurs

Erreurs de syntaxe et erreurs lors de l'exécution

A force d'écrire des lignes de code et de tester vos propres scripts, vous vous êtes rendus compte que, de temps en temps, l'exécution d'un programme générait une erreur. Le plus souvent, elles sont dues au fait que le programme a été mal écrit (erreurs de syntaxe). Mais un programme complètement fonctionnel peut planter aussi à cause d'erreurs commises par l'utilisateur.

Les erreurs qui apparaissent durant l'exécution d'un programme sont appelées exceptions. On peut les gérer avec les instructions try, except, else, finally.

Nous allons traiter ici d'un cas simple, un script qui réalise une division à partir de deux nombres réels (nombres à virgule... ou pas) saisis par l'utilisateur.

Nous avons vu jusque-là que cela se codait ainsi :

# coding: utf-8

print("--- Ce programme réalise la division de a par b ---")
a = input("Saisir le nombre a : ")
a = float(a)                # conversion de la saisie en nombre réel
b = input("Saisir le nombre b : ")
b = float(b)                # conversion de la saisie en nombre réel

resultat = a / b
print(resultat))

Erreurs possibles de l'utilisateur :

  • et si l'utilisateur saisit 0 pour b ? (une division par 0 est impossible) : il y aura un message d'erreur difficilement lisible.
  • et si l'utilisateur saisit du texte au lieu de nombre ? Là encore, erreur.

La solution ?

  • Essayer de faire le calcul avec try.
  • préciser quoi faire si une exception est levée (si une erreur apparaît) avec except.
  • afficher le résultat avec else si l'opération est possible.
# coding: utf-8

try:
   print("--- Ce programme réalise la division de a par b ---")
   a = input("Saisir le nombre a : ")
   a = float(a)
   b = input("Saisir le nombre b : ")
   b = float(b)
   resultat = a / b
except ValueError as detail:
   print("Un des deux nombres que vous avez saisis n'est pas un nombre")
except ZeroDivisionError:
   print("Impossible de diviser par zéro")
else:
   print(resultat)
finally:
   print("Fin du programme")

Comprendre le programme :

  • comme expliqué plus haut, on essaie d'exécuter le bloc d'instructions qui est dans try
  • si une exception est levée (une erreur apparaît), on la gère avec except :
    • ValueError: précise ce que le programme doit faire si la variable saisie est du bon type mais n'est pas conforme à ce qui est attendu (une chaîne au lieu d'un nombre, par exemple)
    • ZeroDivisionError : précise ce que le programme doit faire s'il y a une division par 0
  • une autre : NameError qui précise ce que le programme doit faire si un nom n'est pas trouvé
  • si aucune exception n'est levée, la ou les instructions contenues dans else s'exécutent.
  • enfin, avec finally, on peut insérer un bloc d'instructions qui s'exécutera dans tous les cas.

En plus de ValueError et ZeroDivisionError vues précédemment, on peut citer aussi :

  • ImportError : lorsqu'on tente d'importer une bibliothèque qui n’est pas installée ou dont le nom n'est pas le bon
  • IndexError : lorsque que l’index n’a pas été trouvé dans la séquence, dans une liste
  • KeyError : lorsqu’une clé de dictionnaire n’est pas trouvée
  • FileNotFoundError : quand un fichier n'est pas trouvé, voir exemple ci-dessous

La liste de toutes les exceptions est visible en cliquant sur ce lien

Plus de détails encore

Lors d'une exception, il est possible d'afficher, en plus de notre message, le détail de l'erreur renvoyée par Python :

# coding: utf-8

try:
   print("--- Ce programme réalise la division de a par b ---")
   a = input("Saisir le nombre a : ")
   a = float(a)
   b = input("Saisir le nombre b : ")
   b = float(b)
   resultat = a / b
except ValueError as detailErreur:
   print("Un des deux nombres que vous avez saisis n'est pas un nombre : ", detailErreur)
except ZeroDivisionError as detailErreur:
   print("Impossible de diviser par zéro : ", detailErreur)
else:
   print(resultat)
finally:
   print("Fin du programme")

Application utile

Nous avons utilisé ici l'exemple d'une division.
La gestion des exceptions avec try, except est fort utile dans la manipulation des fichiers :

# coding: utf-8

try:
   fichier = open("fichier_texte.txt","r")
   print(fichier.read())
except FileNotFoundError as detailErreur:
   print("Erreur d'ouverture de fichier :", detailErreur)
finally:
   print("Fin de programme")

A vous de vous exercer !

Pour aller plus loin...

Il est possible de définir ses propres classes d'exception ou déclencher des exceptions (avec raise).
Se référer à la documentation officielle pour en savoir plus https://docs.python.org/fr/3/tutorial/errors.html