Définition
Un programme Python qui plante n'affiche jamais une simple ligne d'erreur, mais un bloc de texte qui peut décourager la première fois qu'on le découvre. Ce bloc n'est pourtant pas du bruit : c'est la seule information complète sur ce qui s'est passé, et savoir la lire fait gagner un temps précieux face à une erreur.
Ce bloc s'appelle le traceback. Il apparaît quand une exception remonte sans être rattrapée, et il retrace le chemin parcouru par l'erreur : quelle ligne l'a déclenchée, quelle fonction appelait celle-là, et ainsi de suite jusqu'au point d'entrée du programme. Voici à quoi il ressemble lorsqu'une commande cherche une clé absente d'un dictionnaire :
Traceback (most recent call last):
File "app.py", line 42, in <module>
total = facturer(commande)
File "facturation.py", line 18, in facturer
return prix * commande["quantite"]
KeyError: 'quantite'Il se lit de bas en haut
Le réflexe naturel consiste à lire ce bloc comme un texte ordinaire, du haut vers le bas. C'est précisément ce qu'il ne faut pas faire, et personne ne le dit jamais clairement. Python empile les blocs à mesure que l'erreur remonte d'une fonction vers celle qui l'a appelée : le bloc le plus récent, donc le plus proche de la cause, se retrouve mécaniquement en bas.
La dernière ligne donne le type d'erreur et son message : c'est ce qui s'est passé. Le bloc juste au-dessus donne l'endroit exact, avec le fichier, la ligne et le code fautif : c'est là que ça s'est passé.
Les blocs restants, au-dessus, racontent comment on en est arrivé là : la chaîne des fonctions qui se sont appelées avant que l'erreur ne survienne. Utile pour le contexte, moins pour trouver la cause elle-même.
Le schéma suivant reprend ces trois niveaux sur l'exemple précédent :
Ce que chaque niveau apporte se résume dans ce tableau :
| Où regarder | Ce qu'on y trouve |
|---|---|
| Dernière ligne | Le type d'erreur et son message |
| Bloc juste au-dessus | Le fichier, la ligne et le code fautif |
| Blocs précédents | La chaîne des appels, du plus récent au plus ancien |
| Première ligne | Le point d'entrée du programme |
La mention « most recent call last », sur la toute première ligne du traceback, confirme cette règle de lecture : l'appel le plus récent est bien celui du bas.
Un piège courant consiste à ouvrir le fichier mentionné tout en haut du traceback, en pensant y trouver la cause. C'est presque toujours le mauvais réflexe : ce bloc est le plus ancien de la pile, souvent le point d'entrée du programme, loin de l'endroit où l'erreur a réellement été déclenchée. Le fichier à ouvrir en premier est celui du bloc juste au-dessus de la dernière ligne.
Trouver son propre code
Sur un projet qui utilise plusieurs bibliothèques, une bonne partie des blocs d'un traceback pointe vers des fichiers qui ne sont pas les vôtres, mais vers des paquets installés dans un environnement virtuel. Les parcourir un par un pour trouver ce qui a réellement cassé fait perdre du temps.
Le réflexe efficace consiste à repérer le dernier bloc qui mentionne un fichier de votre projet. C'est presque toujours là que se trouve la cause, même si l'erreur est techniquement levée trois niveaux plus bas, à l'intérieur d'une bibliothèque.
Depuis Python 3.11, la ligne fautive est parfois soulignée par une rangée d'accents circonflexes qui pointent l'expression précise en cause. Un repère utile quand une ligne enchaîne plusieurs appels, comme a().b().c(), et qu'il faut savoir lequel des trois a échoué.
Une exception chaînée ajoute une seconde partie au traceback, séparée par une phrase reconnaissable. « The above exception was the direct cause of » signale un chaînage volontaire, écrit avec raise ... from : l'auteur a choisi de documenter le lien entre les deux erreurs. « During handling of the above exception » signale au contraire un incident survenu dans un bloc except, sans intention de chaînage.
L'obtenir sans planter
Laisser le traceback s'afficher dans le terminal convient en développement, puisque quelqu'un regarde l'écran. Cela change dès que le code tourne sans surveillance, dans une tâche planifiée ou un service en production : personne ne lit cette sortie, et l'information disparaît au moment où elle serait la plus utile.
Le module traceback de la bibliothèque standard résout ce problème en transformant le rapport en simple texte, récupérable avec une fonction comme format_exc(). Ce texte part alors dans un journal consultable plutôt que dans une sortie que personne ne surveille, ce qui garde l'erreur diagnosticable longtemps après qu'elle s'est produite.
Questions fréquentes
Pourquoi mon traceback ne mentionne-t-il pas la vraie cause ?
Le plus souvent parce qu'un bloc except a intercepté l'erreur d'origine puis en a levé une autre sans la relier explicitement. Ajouter from à ce raise rétablit ce lien : la cause initiale réapparaît alors dans le rapport, juste au-dessus de la nouvelle erreur.
Que signifie « in <module> » ?
Que la ligne se trouve au niveau du fichier lui-même, en dehors de toute fonction. C'est le corps du script, celui qui s'exécute directement au lancement, sans qu'aucune fonction n'ait été appelée pour y arriver.
Comment garder la trace tout en continuant l'exécution ?
En journalisant l'exception à l'intérieur du bloc except, avec un module de journalisation qui enregistre la trace complète plutôt qu'un simple message. Le programme poursuit son exécution, et l'information reste disponible pour un diagnostic ultérieur.