54 votes

Relancez l'exception Python et conservez la trace de la pile

J'essaie d'attraper une exception dans un thread et de la relancer dans le thread principal:

 import threading
import sys

class FailingThread(threading.Thread):
    def run(self):
        try:
            raise ValueError('x')
        except ValueError:
            self.exc_info = sys.exc_info()

failingThread = FailingThread()
failingThread.start()
failingThread.join()

print failingThread.exc_info
raise failingThread.exc_info[1]
 

Cela fonctionne fondamentalement et donne la sortie suivante:

 (<type 'exceptions.ValueError'>, ValueError('x',), <traceback object at 0x1004cc320>)
Traceback (most recent call last):
  File "test.py", line 16, in <module>
    raise failingThread.exc_info[1]
 

Toutefois, la source de l'exception pointe vers la ligne 16, où la nouvelle augmentation a eu lieu. L'exception originale provient de la ligne 7. Comment dois-je modifier le thread principal pour que la sortie se présente comme suit:

 Traceback (most recent call last):
  File "test.py", line 7, in <module>
 

53voto

Duncan Points 25356

Vous devez utiliser tous les trois arguments à soulever:

raise failingThread.exc_info[0], failingThread.exc_info[1], failingThread.exc_info[2]

en passant le traceback objet en tant que troisième argument préserve la pile.

D' help('raise'):

Si un troisième objet est présent et pas None, il doit être un traceback objet (voir la section Le type standard de hiérarchie), et il est substituer à la place de l'emplacement actuel comme le lieu où le exception s'est produite. Si le troisième objet est présent et pas un assurer la traçabilité de l'objet ou de l' None, un TypeError exception est levée. L' trois-forme d'expression de l' raise est utile de re-lever une exception de manière transparente dans une exception à la clause, mais raise sans expressions doit être préférée si l'exception à être relancé était le plus récemment active exception dans le champ d'application actuel.

Dans ce cas particulier, vous ne pouvez pas utiliser le pas de l'expression de la version.

0voto

Ivaylo Petrov Points 483

Pourriez-vous l'écrire un peu comme ceci:

 try:
    raise ValueError('x')
except ValueError as ex:
    self.exc_info = ex
 

et ensuite utiliser le stacktrace de l'exception?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X