Piszę moduł i chcę mieć ujednoliconą hierarchię wyjątków dla wyjątków, które może on wywołać (np. Dziedziczenie z FooError
klasy abstrakcyjnej dla wszystkich foo
wyjątków specyficznych dla modułu). Pozwala to użytkownikom modułu na wychwycenie tych wyjątków i wyraźną obsługę ich w razie potrzeby. Ale wiele wyjątków zgłoszonych z modułu jest zgłaszanych z powodu innego wyjątku; np. niepowodzenie w wykonaniu jakiegoś zadania z powodu błędu OSError w pliku.
To, czego potrzebuję, to „zawinąć” przechwycony wyjątek w taki sposób, aby miał inny typ i inny komunikat , aby informacje były dostępne na wyższych poziomach hierarchii propagacji przez wszystko, co przechwytuje wyjątek. Ale nie chcę stracić istniejącego typu, komunikatu i śladu stosu; to wszystko jest przydatne dla kogoś, kto próbuje debugować problem. Obsługa wyjątków najwyższego poziomu nie jest dobra, ponieważ próbuję udekorować wyjątek, zanim przejdzie dalej w górę stosu propagacji, a program obsługi najwyższego poziomu jest za późno.
Jest to częściowo rozwiązane poprzez wyprowadzenie foo
specyficznych typów wyjątków mojego modułu z istniejącego typu (np. class FooPermissionError(OSError, FooError)
), Ale to nie ułatwia pakowania istniejącego wystąpienia wyjątku w nowy typ ani modyfikowania komunikatu.
Python PEP 3134 „Exception Chaining and Embedded Tracebacks” omawia zmianę zaakceptowaną w Pythonie 3.0 dla „łańcuchowego” obiektów wyjątków, aby wskazać, że nowy wyjątek został zgłoszony podczas obsługi istniejącego wyjątku.
To, co próbuję zrobić, jest powiązane: potrzebuję tego również we wcześniejszych wersjach Pythona i nie potrzebuję go do tworzenia łańcuchów, a tylko do polimorfizmu. Jaki jest właściwy sposób, aby to zrobić?
except Exception as e
-> raise type(e), type(e)(e.message + custom_message), sys.exc_info()[2]
-> to rozwiązanie pochodzi z innego pytania SO . To nie jest ładne, ale funkcjonalne.