J'ai vu beaucoup de messages sur la trace de pile et les exceptions en Python. Mais je n'ai pas trouvé ce dont j'avais besoin.
J'ai un morceau de code Python 2.7 qui peut déclencher une exception. Je voudrais l'attraper et attribuer à une chaîne sa description complète et la trace de la pile qui a provoqué l'erreur (simplement tout ce que nous utilisons pour voir sur la console). J'ai besoin de cette chaîne pour l'imprimer dans une zone de texte dans l'interface graphique.
Quelque chose comme ça:
try:
method_that_can_raise_an_exception(params)
except Exception as e:
print_to_textbox(complete_exception_description(e))
Le problème est: quelle est la fonction complete_exception_description
?
log_error(err)
fonction.Créons un stacktrace décemment compliqué, afin de démontrer que nous obtenons le stacktrace complet:
Journalisation de la trace de pile complète
Une meilleure pratique consiste à configurer un enregistreur pour votre module. Il connaîtra le nom du module et pourra changer de niveau (entre autres attributs, comme les gestionnaires)
Et nous pouvons utiliser cet enregistreur pour obtenir l'erreur:
Quels journaux:
Et donc nous obtenons la même sortie que lorsque nous avons une erreur:
Obtenir juste la chaîne
Si vous voulez vraiment juste la chaîne, utilisez
traceback.format_exc
plutôt la fonction, démontrant la journalisation de la chaîne ici:Quels journaux:
la source
except Exception as e: logger.exception("<<clearly and distinctly describe what failed here>>", exc_info=e)
exc_info
argument attend un "tuple d'exception" alors que leerror
est une instance de l'Exception
objet (ou sous-classe), et il n'est pas nécessaire de passererror
àe
.Avec Python 3, le code suivant formatera un
Exception
objet exactement comme il serait obtenu en utilisanttraceback.format_exc()
:L'avantage étant que seul l'
Exception
objet est nécessaire (grâce à l'__traceback__
attribut enregistré ), et peut donc être plus facilement passé en argument à une autre fonction pour un traitement ultérieur.la source
.__traceback__
ettype
, voir stackoverflow.com/a/58764987/5717886Vous utilisez sys.exc_info () pour collecter les informations et les fonctions du
traceback
module pour les formater. Voici quelques exemples de formatage.La chaîne d'exception entière est à:
la source
Pour ceux qui utilisent Python-3
En utilisant le
traceback
module etexception.__traceback__
on peut extraire la trace de pile comme suit:traceback.extract_stack()
__traceback__
objet d'exception à l'aide detraceback.extract_tb()
traceback.format_list()
Une démonstration simple:
Nous obtenons la sortie suivante lorsque nous appelons
bar()
:la source
Vous pouvez également envisager d'utiliser le module Python intégré, cgitb , pour obtenir de très bonnes informations d'exception bien formatées, y compris les valeurs des variables locales, le contexte du code source, les paramètres de fonction, etc.
Par exemple pour ce code ...
nous obtenons cette sortie d'exception ...
la source
Si vous souhaitez obtenir les mêmes informations lorsqu'une exception n'est pas gérée, vous pouvez faire quelque chose comme ça. Faites
import traceback
et ensuite:J'utilise Python 3.7.
la source
Pour Python 3.5+ :
Ainsi, vous pouvez obtenir la trace de pile de votre exception comme de toute autre exception. Utilisez
traceback.TracebackException
-le (remplacez simplementex
par votre exception):Un exemple étendu et d'autres fonctionnalités pour ce faire:
La sortie sera quelque chose comme ceci:
la source
mes 2 cents:
la source
Si votre objectif est de faire en sorte que le message d'exception et de stacktrace ressemble exactement au cas où python lève une erreur, ce qui suit fonctionne à la fois dans python 2 + 3:
Cela fonctionne en supprimant le dernier
format_stacktrace()
appel de la pile et en rejoignant le reste. Lorsqu'il est exécuté, l'exemple ci-dessus donne la sortie suivante:la source
J'ai défini la classe d'assistance suivante:
Que je pourrai utiliser plus tard comme ceci:
Et plus tard peut le consommer comme ceci:
(Contexte: j'ai été truqué à cause de l'utilisation de
Promise
s avecException
s, qui transmet malheureusement les exceptions levées à un endroit à un gestionnaire on_rejected à un autre endroit, et il est donc difficile d'obtenir le retraçage de l'emplacement d'origine)la source