Kiedy można złapać RuntimeException

W niedawnym projekcie zalecałem przechwycenie RuntimeException w kodzie uprzęży testowej i zarejestrowanie go. Kod przetwarza serię danych wejściowych z bazy danych i nie chcę, aby test został przerwany z powodu awarii któregokolwiek z danych wejściowych (wartości Null, nielegalne argumenty, itp.). Nie trzeba dodawać, że moja sugestia wywołała pasjonującą dyskusję.

Czy łapanie jakiegokolwiek RuntimeException jest dopuszczalne? Jeśli tak, jakie są inne scenariusze, w których można złapać RuntimeExceptions?

Author: james.garriss, 2009-12-31

10 answers

Łapiesz RuntimeException z tego samego powodu, dla którego łapiesz jakikolwiek wyjątek: planujesz coś z nim zrobić. Może uda Ci się poprawić to, co spowodowało wyjątek. Być może po prostu chcesz ponownie rzucić z innym typem wyjątku.

Łapanie i ignorowanie jakiegokolwiek wyjątku jest jednak bardzo złą praktyką.

 82
Author: kdgregory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-11 14:09:14

Jeśli nie możesz poprawić RuntimeException, nie chcesz go złapać...

...tylko prawdziwe z punktu widzenia deweloperów....

Musisz wyłapać wszystkie wyjątki, zanim dotrą do interfejsu użytkownika i sprawić, że twój użytkownik będzie smutny . Oznacza to, że na "najwyższym poziomie"chcesz złapać wszystko, co dzieje się dalej. Następnie możesz poinformować użytkownika, że wystąpił problem, a jednocześnie podjąć działania w celu poinformowania deweloperów, takie jak wysyłanie wiadomości alarmowych lub nieważne...

Jest w zasadzie uważany za błąd danych / programowania, którego nie można zapomnieć, dlatego chcesz ulepszyć przyszłe wersje oprogramowania, a jednocześnie wziąć użytkownika za rękę i poruszać się w kontrolowany sposób...

 30
Author: raoulsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-30 21:28:10

RuntimeException jest przeznaczony do błędów programisty. Jako taki nie powinien być złapany. Jest kilka przypadków, w których powinno być:

  1. Wywołujesz kod, który pochodzi od strony trzeciej, w której nie masz kontroli nad tym, kiedy rzucają wyjątek. Argumentowałbym, że powinieneś to robić indywidualnie i owijać użycie kodu 3rd party w swoich własnych klasach, abyś mógł przekazać wyjątki non-runtime.

  2. Twój program nie może crash i pozostawić ślad stosu dla użytkownika, aby zobaczyć. W tym przypadku powinno to przejść wokół main i wokół wszelkich wątków i kodu obsługi zdarzeń. Program powinien prawdopodobnie zakończyć się, gdy wystąpi taki wyjątek.

W twoim konkretnym przypadku chciałbym zadać pytanie, dlaczego w testach występują błędy RuntimeExceptions - powinieneś je naprawiać,zamiast pracować nad nimi.

Więc powinieneś zagwarantować, że Twój kod rzuca RuntimeExceptions tylko wtedy, gdy chcesz mieć wyjście programu. Funkcja RuntimeExceptions powinna być przechwytywana tylko wtedy, gdy chcesz ją zalogować i zakończyć. Jest to zgodne z intencją RuntimeExceptions.

Możesz spojrzeć na tę dyskusję z innych powodów, które ludzie podają... Osobiście nie znalazłem przekonującego powodu w odpowiedziach.

 15
Author: TofuBeer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:37

Lata temu napisaliśmy Framework systemu sterowania, a Obiekty agenta przechwyciły wyjątki uruchomieniowe, zarejestrowały je, jeśli mogły i kontynuowały.

Tak złapaliśmy Runtime wyjątki, w tym OutOfMemory w naszym kodzie frameworkowym( i wymusiliśmy GC, i to zaskakujące, jak dobrze utrzymywało to nawet dość przeciekający kod.) Mieliśmy kod, który robił bardzo matematyczne rzeczy związane ze światem rzeczywistym; i od czasu do czasu nie-a-Numer dostaje się z powodu drobnych błędów zaokrąglania i to z tym też sobie poradziłem.

Więc w kodzie framework / "must not exit" myślę, że można to uzasadnić. A kiedy to działa to jest całkiem fajne.

Kod był dość solidny, ale uruchamiał sprzęt, a sprzęt czasami daje głupie odpowiedzi.

Został zaprojektowany do pracy bez interwencji człowieka przez miesiące na raz. W naszych testach sprawdził się bardzo dobrze.

Jako część kodu odzyskiwania błędów, może uciekać się do ponownego uruchomienia całego budynku przy użyciu możliwości UPS aby wyłączyć w N minut i włączyć w m minut.

Czasami usterki sprzętowe muszą być zasilane:)

O ile pamiętam, ostatnią deską ratunku po nieudanym cyklu zasilania było wysłanie e-maila do właścicieli, mówiącego "Próbowałem naprawić siebie i nie mogę; problem jest w podsystemie XYZ", i zawierał link do wywołania pomocy technicznej do nas.

Niestety projekt został puszkowany zanim mógł stać się samoświadomy:) >

 7
Author: Tim Williscroft,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-01 05:08:46

W moim kodzie 99% moich WYJĄTKÓW pochodzi z runtime_exception.

Powody, dla których łapię wyjątki to:

  • Catch Log i naprawić problem.
  • Catch Log i wygenerować bardziej szczegółowy wyjątek i wyrzucić
  • Catch Log i rethrow.
  • Catch Log and Kill operation (discard exception)
    • akcja inicjowana przez użytkownika/żądanie nie powiodła się.
      Na przykład obsługa żądań HTTP. Wolałbym, żeby żądana operacja umarła, niż przynieść Serwis wyłączony. (Chociaż korzystnie Obsługa ma wystarczająco dużo sensu, aby zwrócić kod błędu 500.)
    • przypadek testowy przeszedł / nie powiódł się z wyjątkiem.
    • wszystkie wyjątki nie w głównym wątku.
      Zezwalanie wyjątkom na ucieczkę z wątku jest zwykle źle udokumentowane, ale zwykle powoduje zakończenie programu (bez odwijania stosu).
 6
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 21:37:13

Osobiście zawsze mówiono mi, że chcesz złapać wszystkie RuntimeExceptions; jednak chcesz również zrobić coś o wyjątku, na przykład uruchomić failsafe lub ewentualnie po prostu poinformować użytkownika, że wystąpił błąd.

Ostatni projekt Java, nad którym pracowałem, miał podobne podejście, przynajmniej zalogowaliśmy wyjątek, aby Jeśli użytkownik wywołał narzekanie na błąd, mogliśmy dowiedzieć się dokładnie, co się stało i zobaczyć, gdzie błąd wystąpił.

Edit 1: Jak powiedział kdgregory, łapanie i ignorowanie to dwie różne rzeczy, generalnie ludzie są przeciwni temu drugiemu : -)

 3
Author: Topher Fangio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-30 21:19:52

Wszyscy wiemy, że wyjątki sprawdzone i RuntimeExceptions to dwie kategorie WYJĄTKÓW. Zawsze sugeruje się, że zajmiemy się (albo spróbujemy złapać, albo rzucimy) sprawdzonymi wyjątkami, ponieważ są to warunki programowania, w których niestety programista nie może nic zrobić samodzielnie; Podobnie jak FileNotFoundException to nie programista umieszcza pliki na dysku użytkownika, jeśli program próbuje odczytać plik 1.txt, który ma być na f:\ Użytkownika z wypowiedzi:

File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);

Jeśli plik zostanie znaleziony, wszystko jest w porządku, ale w innym przypadku, jeśli plik nie zostanie znaleziony, program zawiesza się z błędem 0 od użytkownika. W tym scenariuszu programista nie zrobił nic złego. Może to być sprawdzony wyjątek, który musi zostać złapany, aby program mógł kontynuować działanie.

Pozwól mi również wyjaśnić drugi scenariusz, z którym pojęcie RuntimeException będzie jasne. Rozważmy następujący kod:

int a = {1,2,3,4,5};
System.out.println(a[9]);

To słabe kodowanie, które generuje ArrayIndexOutOfBoundsException. Który jest przykładem RuntimeException. Tak więc programista nie powinien obsługiwać wyjątku, pozwolić mu zawiesić program, a później naprawić logikę.

 3
Author: sunya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 21:40:14

Łapiesz RuntimeException kiedy chcesz to przetworzyć. Może chcesz zmienić go jako inny wyjątek lub zalogować do pliku lub bazy danych, lub chcesz włączyć jakąś flagę wyjątku w typie return itp.

 2
Author: fastcodejava,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-08 21:41:16

Wyłapujesz RuntimeExceptions (w dowolnym języku: nieoczekiwane wyjątki/"wszystkie" wyjątki), gdy twój program wykonuje wiele podzadań i sensowne jest wykonywanie każdego z nich, zamiast zatrzymywać się w pierwszej nieoczekiwanej sytuacji. Zestaw testów to dobra sytuacja - chcesz wiedzieć, który z wszystkie testy zawiodły, a nie tylko pierwszy test. Kluczową cechą jest to, że każdy test jest niezależny od wszystkich innych - nie ma znaczenia, czy poprzedni test nie Uruchom, ponieważ kolejność i tak nie jest znacząca.

Inną powszechną sytuacją jest serwer; nie chcesz wyłączyć tylko dlatego, że jedno żądanie zostało zniekształcone w sposób, którego się nie spodziewałeś. (Chyba, że jest to naprawdę, naprawdę ważne, aby zminimalizować szanse na niespójny stan.)

W każdej z tych sytuacji, właściwą rzeczą do zrobienia jest zalogowanie / zgłoszenie wyjątku i kontynuowanie pozostałych zadań.

Można by niejasno uogólnić do każdego wyjątku: "właściwe jest catch " wyjątek wtedy i tylko wtedy, gdy jest coś sensownego do zrobienia po złapanie go: Jak twój program powinien kontynuować .

 1
Author: Kevin Reid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-30 21:48:30

Jeśli można oczekiwać, że klient odzyska kontrolę po wyjątku, zrób z niego wyjątek sprawdzony.

Jeśli klient nie może zrobić nic, aby odzyskać wyjątek, ustaw go jako wyjątek niezaznaczony.

Oto najważniejsze wytyczne.

From Java Docs . Proszę przeczytać to Unchecked Exceptions-the Controversy

 0
Author: VedX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-01 09:58:21