Chapitre 18 : Gestion des erreurs

         1 – Présentation

    La gestion des erreurs permet d’éviter que votre programme plante en prévoyant vous même les sources d’erreurs éventuelles.

Voici un exemple dans lequel on demande à l’utilisateur d’entrer un nombre, puis on affiche ce nombre.

Code python

>>> nb = int(raw_input(« Entrez un nombre: « ))
Entrez un nombre: 23
>>> print nb
23
La fonction raw_input() permet à l’utilisateur de saisir une chaîne de caractères. Cette chaîne de caractères est ensuite transformée en nombre entier avec la fonction int().

Si l’utilisateur ne rentre pas un nombre, voici ce qui se passe :

Code python

>>> nb = int(raw_input(« Entrez un nombre: « ))
Entrez un nombre: ATCG
Traceback (most recent call last):
File « <stdin> », line 1, in <module>
ValueError: invalid literal for int() with base 10: ‘ATCG’
L’erreur provient de la fonction int() qui n’a pas pu convertir la chaîne de caractères « ATCG » en nombre, ce qui est normal.

Le jeu d’instruction try / except permet de tester l’exécution d’une commande et d’intervenir en cas d’erreur.

Code python

>>> try:
… nb = int(raw_input(« Entrez un nombre: « ))
… except:
… print « Vous n’avez pas entré un nombre ! »

Entrez un nombre: ATCG
Vous n’avez pas entré un nombre !
Dans cette exemple, l’erreur renvoyée par la fonction int() (qui ne peut pas convertir « ATCG » en nombre) est interceptée et déclenche l’affichage du message d’avertissement.

On peut ainsi redemander sans cesse un nombre à l’utilisateur, jusqu’à ce que celui-ci en rentre bien un.

Code python

>>> while 1:
… try:
… nb = int(raw_input(« Entrez un nombre: « ))
… print « Le nombre est », nb
… break
… except:
… print « Vous n’avez pas entré un nombre ! »
… print « Essayez encore »

Entrez un nombre: ATCG
Vous n’avez pas entré un nombre !
Essayez encore
Entrez un nombre: toto
Vous n’avez pas entré un nombre !
Essayez encore
Entrez un nombre: 55
Le nombre est 55
Notez que dans cet exemple, l’instruction while 1 est une boucle infinie (car la condition 1 est toujours vérifiée) dont l’arrêt est forcé par la commande break lorsque l’utilisateur a effectivement bien rentré un nombre.

La gestion des erreurs est très utile dès lors que des données extérieures entrent dans le programme, que ce soit directement par l’utilisateur (avec la fonction raw_input()) ou par des fichiers.

Vous pouvez par exemple vérifier qu’un fichier a bien été ouvert.

Code python

>>> nom = « toto.pdb »
>>> try:
… f = open(nom, « r »)
… except:
… print « Impossible d’ouvrir le fichier », nom
Si une erreur est déclenchée, c’est sans doute que le fichier n’existe pas à l’emplacement indiqué sur le disque ou que (sous Unix), vous n’ayez pas les droits d’accès pour le lire.

Il est également possible de spécifier le type d’erreur à gérer. Le premier exemple que nous avons étudié peut s’écrire :

Code python

>>> try:
… nb = int(raw_input(« Entrez un nombre: « ))
… except ValueError:
… print « Vous n’avez pas entré un nombre ! »

Entrez un nombre: ATCG
Vous n’avez pas entré un nombre !
Ici, on intercepte une erreur de type ValueError, ce qui correspond bien à un problème de conversion avec int(). Il existe d’autres types d’erreurs comme RuntimeError, TypeError, NameError, IOError, etc.

Enfin, on peut aussi être très précis dans le message d’erreur. Observez la fonction downloadPage() qui, avec le module urllib2, télécharge un fichier sur internet.

Code python

import urllib2

def downloadPage(address):
error = «  »
page = «  »
try:
data = urllib2.urlopen(address)
page = data.read()
except IOError, e:
if hasattr(e, ‘reason’):
error = « Cannot reach web server:  » + str(e.reason)
if hasattr(e, ‘code’):
error = « Server failed %d » %(e.code)
return page, error
La variable e est une instance (un représentant) de l’erreur de type IOError. Certains de ces attributs sont testés avec la fonction hasattr() pour ainsi affiner le message renvoyé (ici contenu dans la variable error).