Metoda A wywołuje metodę B, która z kolei wywołuje metodę C.
Nie ma obsługi wyjątków w metodzie B lub metodzie C. Ale istnieje metoda obsługi wyjątków w metodzie A.
W metodzie C występuje wyjątek.
Teraz wyjątek dotyczy metody MethodA, która odpowiednio ją obsługuje.
Co jest z tym nie tak?
Moim zdaniem, w pewnym momencie program wywołujący wykona metodę B lub metodę C, a gdy w tych metodach wystąpią wyjątki, to co zyska się na obsłudze wyjątków w tych metodach, co zasadniczo jest tylko blokiem try / catch / wreszcie zamiast po prostu pozwolić oni bańki do callee?
Oświadczenie lub konsensus dotyczący obsługi wyjątków ma zostać wygenerowany, gdy wykonanie nie może być kontynuowane z tego właśnie powodu - wyjątku. Rozumiem. Ale dlaczego nie złapać wyjątku w dalszej części łańcucha zamiast blokowania try / catch do samego końca.
Rozumiem to, kiedy musisz zwolnić zasoby. To zupełnie inna sprawa.
źródło
try-catch
blok nie jest wcale potrzebny .Result<T>
typ (typ, który przechowuje wynik obliczeń lub błąd) i zwrócić go z innych funkcji rzucania. Propagowanie błędu na stosie wiązałoby się z odczytaniem każdej zwracanej wartości, sprawdzaniem, czy jest to błąd i zwracaniem błędu, jeśli tak jest.Odpowiedzi:
Zgodnie z ogólną zasadą nie wychwytuj wyjątków, chyba że wiesz, co z nimi zrobić. Jeśli MethodC zgłasza wyjątek, ale MethodB nie ma użytecznego sposobu na jego obsłużenie, wówczas powinien umożliwić wyjątek rozprzestrzenienie się do MethodA.
Jedynymi powodami, dla których metoda powinna mieć mechanizm catch and rethrow, są:
W przeciwnym razie wychwytywanie wyjątków na niewłaściwym poziomie powoduje, że kod po cichu zawodzi bez dostarczania użytecznych informacji zwrotnych do kodu wywołującego (i ostatecznie użytkownika oprogramowania). Alternatywa złapania wyjątku, a następnie natychmiastowego jego ponownego wprowadzenia jest bezcelowa.
źródło
try ... finally ...
, użyj tego, nieLoadDataException
I dołącz oryginalne szczegóły wyjątku zgodnie z funkcjami języka, aby przyszli opiekunowie mogli zobaczyć główną przyczynę bez konieczności dołączania debuggera i wymyślania, jak odtworzyć problem.Absolutnie niczego.
„odpowiednio sobie z tym radzi” jest ważną częścią. To sedno obsługi strukturalnego wyjątku.
Jeśli Twój kod może zrobić coś „użytecznego” z wyjątkiem, skorzystaj z niego. Jeśli nie, to daj spokój.
Właśnie to powinieneś robić. Jeśli czytasz kod, który ma handler / rethrowers „do samego końca”, to [prawdopodobnie] czytasz jakiś dość kiepski kod.
Niestety, niektórzy programiści widzą bloki catch jako kod „bojlera”, który wrzucają (bez zamierzonej gry słów) do każdej pisanej metody, często dlatego, że tak naprawdę nie „dostają” obsługi wyjątków i uważają, że muszą coś dodać wyjątki nie „uciekają” i nie zabijają ich programów.
Częściową trudnością jest to, że przez większość czasu problem ten nawet nie zostanie zauważony, ponieważ wyjątki nie są zgłaszane przez cały czas, ale kiedy już się pojawią , program będzie marnował dużo czasu i staraj się stopniowo usuwać stos wywołań, aby dostać się do miejsca, które faktycznie robi coś przydatnego w przypadku wyjątku.
źródło
catch
na najwyższym poziomie, który rejestruje błąd i zwraca odpowiedź błędu.catch
Wszędzie nie posypano bloków. Jeśli nie masz ochoty wymieniać każdego możliwego sprawdzonego wyjątku (w językach takich jak Java), po prostu zawiń goRuntimeException
zamiast tam logować, próbując kontynuować i napotkać więcej błędów, a nawet luk.Musisz zrobić różnicę między bibliotekami a aplikacjami.
Biblioteki mogą swobodnie zgłaszać niewyłapane wyjątki
Projektując bibliotekę, w pewnym momencie musisz pomyśleć o tym, co może pójść nie tak. Parametry mogą znajdować się w niewłaściwym zakresie lub
null
zasoby zewnętrzne mogą być niedostępne itp.Twoja biblioteka najczęściej nie będzie miała sposobu, aby sobie z nimi poradzić w rozsądny sposób. Jedynym sensownym rozwiązaniem jest zgłoszenie odpowiedniego wyjątku i pozwolenie deweloperowi aplikacji zająć się tym.
Aplikacje powinny zawsze w pewnym momencie wychwytywać wyjątki
Kiedy wychwycony jest wyjątek, lubię je kategoryzować jako Błędy lub Błędy krytyczne . Zwykły błąd oznacza, że pojedyncza operacja w mojej aplikacji nie powiodła się. Na przykład nie można zapisać otwartego dokumentu, ponieważ nie można było zapisać miejsca docelowego. Jedyną rozsądną rzeczą, jaką może zrobić Aplikacja, jest poinformowanie użytkownika, że operacja nie może zostać pomyślnie zakończona, podanie czytelnych dla człowieka informacji dotyczących problemu, a następnie pozwolenie użytkownikowi zdecydować, co dalej.
Fatal Error jest błąd główny logika aplikacji nie można odzyskać. Na przykład, jeśli sterownik urządzenia graficznego ulegnie awarii w grze wideo, Aplikacja nie będzie mogła „z wdziękiem” poinformować użytkownika. W takim przypadku należy zapisać plik dziennika i, jeśli to możliwe, użytkownik powinien zostać w taki czy inny sposób poinformowany.
Nawet w tak poważnym przypadku Aplikacja powinna traktować ten wyjątek w znaczący sposób. Może to obejmować zapisanie pliku dziennika, wysłanie raportu o awarii itp. Nie ma powodu, aby aplikacja nie reagowała w jakiś sposób na wyjątek.
źródło
HDDPluggedOutDuringWritingException
może można sobie z tym poradzić i nie jest to fatalne dla aplikacji. Program może zdecydować, co z tym zrobić.Co jest nie tak z opisanym wzorcem, że metoda A nie będzie w stanie odróżnić trzech scenariuszy:
Metoda B zawiodła w oczekiwany sposób.
Metoda C zawiodła w sposób nieprzewidziany w metodzie B, ale podczas gdy metoda B wykonywała operację, którą można bezpiecznie porzucić.
Metoda C zawiodła w sposób nieprzewidziany w metodzie B, ale podczas gdy metoda B przeprowadzała operację, która ustawiła rzeczy w rzekomo tymczasowy niespójny stan, którego B nie udało się wyczyścić z powodu awarii C.
Jedynym sposobem, w jaki metoda A będzie w stanie rozróżnić te scenariusze, będzie sytuacja, gdy wyjątek zgłoszony z B będzie zawierał informacje wystarczające do tego celu lub jeśli rozwinięcie stosu dla metody B spowoduje pozostawienie obiektu w jawnie unieważnionym stanie. Niestety większość ram wyjątków sprawia, że oba wzorce są niewygodne, co zmusza programistów do podejmowania decyzji projektowych „mniejszego zła”.
źródło