Widziałem wiele postów dotyczących śledzenia stosu i wyjątków w Pythonie. Ale nie znalazłem tego, czego potrzebuję.
Mam fragment kodu Python 2.7, który może zgłosić wyjątek. Chciałbym go złapać i przypisać ciągowi pełny opis i ślad stosu, który spowodował błąd (po prostu wszystko, co widzimy na konsoli). Potrzebuję tego ciągu, aby wydrukować go do pola tekstowego w GUI.
Coś takiego:
try:
method_that_can_raise_an_exception(params)
except Exception as e:
print_to_textbox(complete_exception_description(e))
Problemem jest: jaka jest funkcja complete_exception_description
?
python
python-2.7
exception-handling
stack-trace
niebieskawy
źródło
źródło
log_error(err)
funkcję.Stwórzmy dość skomplikowane śledzenie stosu, aby pokazać, że otrzymujemy pełny stos śledzenia:
Rejestrowanie pełnego śledzenia śledzenia
Najlepszą praktyką jest skonfigurowanie rejestratora dla modułu. Będzie znał nazwę modułu i będzie mógł zmieniać poziomy (między innymi atrybutami, takimi jak moduły obsługi)
I możemy użyć tego rejestratora, aby uzyskać błąd:
Które dzienniki:
Otrzymujemy takie same dane wyjściowe, jak w przypadku błędu:
Uzyskiwanie tylko sznurka
Jeśli naprawdę chcesz po prostu napisu, użyj
traceback.format_exc
zamiast niego funkcji, demonstrując rejestrowanie napisu tutaj:Które dzienniki:
źródło
except Exception as e: logger.exception("<<clearly and distinctly describe what failed here>>", exc_info=e)
exc_info
argument oczekuje „krotki wyjątku”, podczas gdyerror
jest instancjąException
obiektu (lub podklasy) i nie ma potrzeby zmianyerror
nae
.W Pythonie 3 następujący kod sformatuje
Exception
obiekt dokładnie tak, jak można go uzyskać za pomocątraceback.format_exc()
:Zaletą jest to, że
Exception
potrzebny jest tylko obiekt (dzięki zarejestrowanemu__traceback__
atrybutowi), a zatem można go łatwiej przekazać jako argument do innej funkcji w celu dalszego przetwarzania.źródło
.__traceback__
itype
, patrz stackoverflow.com/a/58764987/5717886Użyć sys.exc_info () , aby zebrać informacje i funkcje w
traceback
module, aby go sformatować. Tutaj kilka przykładów jego formatowania.Cały ciąg wyjątku znajduje się w:
źródło
Dla osób używających Python-3
Za pomocą
traceback
modułuexception.__traceback__
można wyodrębnić ślad stosu w następujący sposób:traceback.extract_stack()
__traceback__
obiekt wyjątku za pomocątraceback.extract_tb()
traceback.format_list()
Prosta demonstracja:
Gdy wywołujemy, otrzymujemy następujące dane wyjściowe
bar()
:źródło
Możesz także rozważyć użycie wbudowanego modułu Python, cgitb , aby uzyskać naprawdę dobre, ładnie sformatowane informacje o wyjątkach, w tym wartości zmiennych lokalnych, kontekst kodu źródłowego, parametry funkcji itp.
Na przykład dla tego kodu ...
otrzymujemy ten wyjątek wyjściowy ...
źródło
Jeśli chcesz uzyskać te same informacje, gdy wyjątek nie jest obsługiwany, możesz zrobić coś takiego. Zrób,
import traceback
a następnie:Używam Python 3.7.
źródło
W przypadku Python 3.5+ :
Możesz więc pobrać śledzenie stosu ze swojego wyjątku, jak z każdego innego wyjątku. Użyj
traceback.TracebackException
do tego (po prostu zastąpex
swoim wyjątkiem):Rozszerzony przykład i inne funkcje do tego celu:
Wynik będzie mniej więcej taki:
źródło
moje 2 centy:
źródło
Jeśli Twoim celem jest, aby wyjątek i komunikat stacktrace wyglądały dokładnie tak, jak gdy python zgłasza błąd, poniższe działania działają zarówno w python 2 + 3:
Działa poprzez usunięcie ostatniego
format_stacktrace()
wywołania ze stosu i dołączenie do reszty. Po uruchomieniu powyższy przykład daje następujące dane wyjściowe:źródło
Zdefiniowałem następującą klasę pomocnika:
Którego później mogę użyć w następujący sposób:
A później można go spożywać w ten sposób:
(Tło: Byłem sfrustrowany, ponieważ używałem
Promise
s razem zException
s, co niestety przekazuje wyjątki podniesione w jednym miejscu do procedury obsługi on_rejected w innym miejscu, a zatem trudno jest odzyskać traceback z pierwotnej lokalizacji)źródło