Comment puis-je lever une exception python avec plusieurs causes, similaire à celle de Java fonctionnalité addSuppressed () ? Par exemple, j'ai une liste de plusieurs méthodes à essayer et si aucune d'entre elles ne fonctionne, je veux lever une exception qui inclut les exceptions de toutes les méthodes qui ont été essayées. C'est-à-dire :
exceptions = [] for method in methods_to_try: try: method() except Exception as e: exceptions.append(e) if exceptions: raise Exception("All methods failed") from exceptions
Mais ce code échoue car l'instruction rise ... from ...
attend une seule exception et non une liste. Les solutions Python 2 ou 3 sont acceptables. Toutes les traces de retour et tous les messages d'exception doivent être préservés.
3 Réponses :
Si l'utilisation du module de journalisation est acceptable pour vous, je suppose que ce serait le plus propre de consigner les exceptions individuelles que vous avez détectées et de ne lever qu'une seule exception globale.
Si vous souhaitez uniquement afficher les messages du journal en cas d'erreur de toutes les fonctions essayées, c'est un cas idéal pour le logger tamponné de journal de recettes de journalisation Vous pouvez le modifier pour toujours vous connecter au niveau de débogage, mais augmenter le niveau en erreur, si toutes les sous-fonctions génèrent une erreur.
La journalisation crée des effets secondaires indésirables pour le code. Je recherche un moyen de conserver plusieurs exceptions / retraits dans une seule exception soulevée.
Il suffit de transmettre les exceptions comme arguments lors de la création de la dernière exception.
for method in methods_to_try: try: method() except Exception as e: exceptions.append(e) if exceptions: raise Exception(*exceptions)
Elles seront disponibles dans l'attribut args
.
Je ne vois toujours que le traçage de la dernière exception soulevée. Je recherche une solution qui préserve tous les retraits.
@Evan Les traces sont à l'intérieur des exceptions, si vous voulez les imprimer, vous devez écrire le code. AFAIK la gestion python par défaut ne peut pas faire ce que vous voulez. Consultez le module traceback
pour obtenir de l'aide.
Seules les exceptions python 3 ont __traceback__
. Sur python 2, vous pouvez utiliser sys.exc_info
pour stocker le traçage avant d'ajouter l'exception.
Une fois pourrait lever chaque exception de l'autre pour l'enchaîner. Le seul problème concerne l'ordre de cause qui peut être trompeur.
def combine_exc(exceptions): c_exc = None for ex in reversed(exceptions): try: if c_exc is None: raise ex else: raise ex from c_exc except Exception as ex1: c_exc = ex1 return c_exc
vous ne pouvez pas lever plusieurs exceptions. Créez une grande exception avec toutes les traces de pile et augmentez-la. Ça va être moche