En Python, la gestion des exceptions est mise en œuvre à travers les constructions try/except/else/finally et l'opérateur raise.
try définit un bloc de code protégé. Si une exception se produit à l'intérieur, le contrôle est transféré au bloc except correspondant le plus proche. S'il n'y a pas d'exception, le bloc else est exécuté, s'il existe. Le bloc finally est toujours exécuté — qu'une exception se soit produite ou non (par exemple, pour libérer des ressources).
L'opérateur raise déclenche une exception explicitement ou relance l'actuelle (dans le bloc except sans spécification de type).
Exemple :
try: x = 1 / 0 except ZeroDivisionError as e: print(f"Erreur : {e}") else: print("Pas d'erreur") finally: print("Toujours exécuté")
Sortie :
Erreur : division par zéro
Toujours exécuté
Subtilités :
Question : « Que se passe-t-il si dans le bloc try et dans le finally, vous appelez raise avec des exceptions différentes ? »
Réponse : L'exception du finally "couvre" l'exception du try : ce qui sortira sera celui qui a été déclenché dans le finally.
def foo(): try: raise ValueError("dans try") finally: raise IndexError("dans finally") try: foo() except Exception as e: print(repr(e)) # Affichera : IndexError('dans finally')
Histoire
Dans un processus ETL, la connexion à la base était systématiquement fermée dans le bloc finally, mais on oubliait que cela pouvait déclencher une exception (par exemple, si la connexion était déjà fermée). Au final — une exception "cachée" dans finally absorbait complètement l'exception du code principal, rendant le débogage beaucoup plus difficile.
Histoire
Des chaînes de plusieurs except ont été utilisées : un except Exception général au-dessus des spécifiques. Par conséquent, tous les except spécifiques restaient "morts" — les exceptions à faible niveau n'étaient pas attrapées séparément, ce qui compliquait le traitement des erreurs spécifiques.
Histoire
Dans un service web, dans le except du bloc, on oubliait de relancer l'exception via "raise", en journalisant l'erreur, mais en permettant à l'exécution de continuer. Au final, les véritables erreurs "se perdaient", et le programme continuait à fonctionner avec un état incorrect.