Comment imprimer une exception en Python?

Réponses:

1064

Pour Python 2.6 et versions ultérieures et Python 3.x:

except Exception as e: print(e)

Pour Python 2.5 et versions antérieures, utilisez:

except Exception,e: print str(e)
jldupont
la source
41
str( KeyError('bad'))=> 'bad'- ne dit pas le type d'exception
Dave
10
print (e) sur les erreurs de clé semble donner uniquement la clé, mais pas le message d'exception complet, ce qui est loin d'être utile.
Veggiet
14
Si vous allez imprimer l'exception, il est préférable de l'utiliser print(repr(e)); l' Exception.__str__implémentation de base renvoie uniquement le message d'exception, pas le type. Ou, utilisez le tracebackmodule, qui dispose de méthodes pour imprimer l'exception actuelle, formatée ou la trace complète.
Martijn Pieters
453

Le tracebackmodule fournit des méthodes pour formater et imprimer les exceptions et leurs retraits, par exemple, cela afficherait l'exception comme le gestionnaire par défaut:

import traceback

try:
    1/0
except Exception:
    traceback.print_exc()

Production:

Traceback (most recent call last):
  File "C:\scripts\divide_by_zero.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero
Cat Plus Plus
la source
4
existe-t-il une sorte d'appel get_error_message que je peux imprimer en voyant que j'utilise ma propre routine d'impression pour ajouter d'autres choses.
MikeSchem
11
@MikeSchem error_message = traceback.format_exc()
heyzling
3
Merci, c'est celui que je voulais. Trace entière, pas seulement le type d'erreur et le message
Ken Bellows
Cet extrait n'utilise pas l'objet d'exception capturé. Pouvez-vous développer le code pour utiliser «ex»? - comme dans except Exception as ex:...
aaronsteers
@aaronsteers, il utilise l'exception capturée; dans un gestionnaire d'exceptions, l'exception actuelle est disponible via la sys.exc_info()fonction et la traceback.print_exc()fonction l'obtient à partir de là. Vous n'auriez besoin que de transmettre une exception de manière explicite lorsque vous ne gérez pas d'exception ou lorsque vous souhaitez afficher des informations basées sur une exception différente.
Martijn Pieters
169

En Python 2.6 ou supérieur, c'est un peu plus propre:

except Exception as e: print(e)

Dans les anciennes versions, il est encore assez lisible:

except Exception, e: print e
ilya n.
la source
15
En python3, il faut utiliser la 1ère voie, avec "as".
Sam Watkins
53

Si vous souhaitez transmettre des chaînes d'erreur, voici un exemple tiré d' Erreurs et exceptions (Python 2.6)

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print type(inst)     # the exception instance
...    print inst.args      # arguments stored in .args
...    print inst           # __str__ allows args to printed directly
...    x, y = inst          # __getitem__ allows args to be unpacked directly
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
Nick Dandoulakis
la source
38

(J'allais laisser cela comme un commentaire sur la réponse de @ jldupont, mais je n'ai pas assez de réputation.)

J'ai vu des réponses comme la réponse de @ jldupont dans d'autres endroits également. FWIW, je pense qu'il est important de noter que ceci:

except Exception as e:
    print(e)

affichera la sortie d'erreur sys.stdoutpar défaut. Une approche plus appropriée de la gestion des erreurs en général serait:

except Exception as e:
    print(e, file=sys.stderr)

(Notez que vous devez le faire import sysfonctionner.) De cette façon, l'erreur est imprimée sur au STDERRlieu deSTDOUT , ce qui permet une analyse / redirection / etc correcte de la sortie. Je comprends que la question portait strictement sur `` l'impression d'une erreur '', mais il semble important de souligner ici la meilleure pratique plutôt que de laisser de côté ce détail qui pourrait conduire à un code non standard pour quiconque n'apprendrait finalement pas mieux.

Je n'ai pas utilisé le tracebackmodule comme dans la réponse de Cat Plus Plus, et c'est peut-être la meilleure façon, mais je pensais que je mettrais ça là-bas.

grish
la source
1
Je suggère d'ajouter encore flush = True. J'ai remarqué avec systemd (et sans utiliser un cadre de journalisation approprié), que la mise en mémoire tampon lors de la capture dans le journal n'est pas ce à quoi je m'attendais.
Cameron Kerr
20

Python 3: logging

Au lieu d'utiliser la print()fonction de base , le loggingmodule plus flexible peut être utilisé pour enregistrer l'exception. Le loggingmodule offre de nombreuses fonctionnalités supplémentaires, par exemple la journalisation des messages dans un fichier journal donné, la journalisation des messages avec des horodatages et des informations supplémentaires sur le lieu de la journalisation. (Pour plus d'informations, consultez la documentation officielle .)

La journalisation d'une exception peut être effectuée avec la fonction au niveau du module logging.exception()comme ceci:

import logging

try:
    1/0
except BaseException:
    logging.exception("An exception was thrown!")

Production:

ERROR:root:An exception was thrown!
Traceback (most recent call last):
  File ".../Desktop/test.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero 

Remarques:

  • la fonction logging.exception()ne doit être appelée qu'à partir d'un gestionnaire d'exceptions

  • le loggingmodule ne doit pas être utilisé dans un gestionnaire de journalisation pour éviter un RecursionError(merci @PrakharPandey)


Niveaux de journalisation alternatifs

Il est également possible de consigner l'exception avec un autre niveau de journal en utilisant l'argument mot-clé exc_info=Truecomme ceci:

logging.debug("An exception was thrown!", exc_info=True)
logging.info("An exception was thrown!", exc_info=True)
logging.warning("An exception was thrown!", exc_info=True)
winklerrr
la source
1
Ne doit pas être utilisé dans un gestionnaire de journalisation pour éviter RecursionError
Prakhar Pandey
4

Une augmentation d'erreur de ligne peut être effectuée avec des instructions assert si c'est ce que vous voulez faire. Cela vous aidera à écrire du code statiquement réparable et à vérifier les erreurs tôt.

assert type(A) is type(""), "requires a string"
quoi
la source
2

On a à peu près le contrôle sur les informations du traçage à afficher / enregistrer lors de la capture des exceptions.

Le code

with open("not_existing_file.txt", 'r') as text:
    pass

produirait le retraçage suivant:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Imprimer / enregistrer la trace complète

Comme d'autres l'ont déjà mentionné, vous pouvez récupérer l'intégralité du traceback en utilisant le module traceback:

import traceback
try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    traceback.print_exc()

Cela produira la sortie suivante:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Vous pouvez obtenir le même résultat en utilisant la journalisation:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    logger.error(exception, exc_info=True)

Production:

__main__: 2020-05-27 12:10:47-ERROR- [Errno 2] No such file or directory: 'not_existing_file.txt'
Traceback (most recent call last):
  File "exception_checks.py", line 27, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Nom / message d'erreur d'impression / de journalisation uniquement

Vous pourriez ne pas être intéressé par l'intégralité du traçage, mais uniquement par les informations les plus importantes, telles que le nom et le message d'exception, utilisez:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    print("Exception: {}".format(type(exception).__name__))
    print("Exception message: {}".format(exception))

Production:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'
Gin tonic
la source