Рассмотрим следующую тривиальную программу:
Код: Выделить всё
class OriginalException(Exception):
pass
class AnotherException(Exception):
pass
def raise_another_exception():
raise AnotherException()
def show_something():
try:
raise OriginalException()
except OriginalException:
raise_another_exception()
show_something()
Код: Выделить всё
Traceback (most recent call last):
File "...../stackoverflow_single_complication.py", line 15, in show_something t1
raise OriginalException()
__main__.OriginalException
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "...../stackoverflow_single_complication.py", line 20, in t0
show_something()
File "...../stackoverflow_single_complication.py", line 17, in show_something t2
raise_another_exception()
File "...../stackoverflow_single_complication.py", line 10, in raise_another_exception t3
raise AnotherException()
__main__.AnotherException
Затем мы видим AnotherException
code> с полной трассировкой от точки поднятия до начала программы (все кадры)
Само по себе это прекрасно, но следствием такого способа представления информации является то, что кадры стека не располагаются на экране в том порядке, в котором они были вызваны (а не в обратном порядке), как указано в аннотациях < em>t1, t0, t2, t3. Путь, ведущий к t1, конечно же, такой же, как путь, ведущий к t2, и создатели Python решили представить его только один раз, в последнем случае. , предположительно потому, что это исключение обычно является наиболее интересным и потому что оно позволяет читать нижнее исключение снизу вверх без потери информации. Однако это оставляет людей, желающих проанализировать OriginalException, в некотором замешательстве: что к этому привело?
Программист, который хочет понять, что привело к t1 потребуется [мысленно] скопировать все кадры выше точки t2 в первую трассировку стека, чтобы получить полное представление. Однако на самом деле точка t2, AFAIK, не аннотируется автоматически как специальный кадр, что значительно усложняет задачу мысленного копирования трассировки стека.
Поскольку точка t2 обычно является «неудачной строкой в блоке исключений», путем перекрестных ссылок на исходный код это упражнение обычно можно завершить, но это кажется излишне трудным.
Можно ли автоматически определить t2 как «фрейм обработки»?
(Приведенный выше пример приведен без какого-либо внешнего контекста обработки исключений; меня вполне устраивают ответы, которые его представляют, а затем используют трассировку или другие инструменты для получения правильного ответа).
Это самый тривиальный случай, иллюстрирующий проблему; реальные случаи имеют гораздо больше стековых фреймов и, следовательно, менее четко иллюстрируют проблему, но более четко иллюстрируют необходимость (потенциально автоматизированного) разъяснения того, что происходит, о чем идет речь в этом вопросе SO.
Изменить, чтобы добавить :
Я написал полную публикацию в блоге о цепочке исключений в Python.
Подробнее здесь: https://stackoverflow.com/questions/782 ... n-an-excep