J'écris un module et je souhaite avoir une hiérarchie d'exceptions unifiée pour les exceptions qu'il peut soulever (par exemple, hériter d'une FooError
classe abstraite pour toutes les foo
exceptions spécifiques du module). Cela permet aux utilisateurs du module d'attraper ces exceptions particulières et de les gérer distinctement, si nécessaire. Mais la plupart des exceptions levées à partir du module sont déclenchées à cause d'une autre exception; par exemple, échec d'une tâche à cause d'une erreur OSError sur un fichier.
Ce dont j'ai besoin, c'est «d'envelopper» l'exception capturée de telle sorte qu'elle ait un type et un message différents , de sorte que les informations soient disponibles plus haut dans la hiérarchie de propagation par tout ce qui intercepte l'exception. Mais je ne veux pas perdre le type, le message et la trace de pile existants; ce sont toutes des informations utiles pour quelqu'un qui essaie de déboguer le problème. Un gestionnaire d'exceptions de niveau supérieur n'est pas bon, car j'essaie de décorer l'exception avant qu'elle ne monte plus haut dans la pile de propagation, et le gestionnaire de niveau supérieur est trop tard.
Ceci est en partie résolu en dérivant les foo
types d'exceptions spécifiques de mon module à partir du type existant (par exemple class FooPermissionError(OSError, FooError)
), mais cela ne facilite pas l'encapsulation de l'instance d'exception existante dans un nouveau type, ni ne modifie le message.
Le PEP 3134 de Python «Chaînage d'exceptions et traçages intégrés» traite d'un changement accepté dans Python 3.0 pour le «chaînage» des objets d'exception, pour indiquer qu'une nouvelle exception a été déclenchée lors de la gestion d'une exception existante.
Ce que j'essaie de faire est lié: j'en ai besoin aussi pour les versions antérieures de Python, et j'en ai besoin non pas pour le chaînage, mais uniquement pour le polymorphisme. Quel est le bon moyen de le faire?
except Exception as e
-> raise type(e), type(e)(e.message + custom_message), sys.exc_info()[2]
-> cette solution provient d'une autre question SO . Ce n'est pas joli mais fonctionnel.