• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dlaczego rzucanie ogólnego wyjątku Exception przez metodę jest złą praktyką?

VPS Starter Arubacloud
0 głosów
411 wizyt
pytanie zadane 15 września 2016 w Java przez rj45 Nowicjusz (120 p.)

Witam. Czy, może ktoś solidnie, z przykładem powiedzieć i udowodnić dlaczego rzucanie ogólnego wyjątku Exception w Javie jest złe i nie powinno się tego robić? Napisałem taki prosty kawałek kodu:

public class Point {

    public void m(int x) throws Exception{
	
	    if(x == 1) throw new IllegalAccessException();
	    else if (x == 2) throw new InstantiationException();
	    else if (x == 3) throw new CloneNotSupportedException();
	    else throw new NoSuchFieldException();

    }
    
    public static void main(String[] args){

	Point p1 = new Point();
	
	try{
	       
	    p1.m(1);
	       
	}
	catch(IllegalAccessException e){
	       
	    System.err.println(e);
	    System.err.println("ILLEGAL ACCESS");
	       
	}
	catch(InstantiationException e){
	       
	    System.err.println(e);
	    System.err.println("INSTANTIATION");
	       
	}
	 catch(CloneNotSupportedException e){
	       
	    System.err.println(e);
	    System.err.println("CLONE");
	       
	}
	catch(Exception e){
	       
	    System.err.println(e);
	    System.err.println("EXCEPTION");
	       
	   }
	   		   
    }
    
}

Przerzuciłem kiladziesiąt stron w poszukiwaniu odpowiedzi i być może jej nie rozumiem. Ludzie piszą na stacku, żę jeżeli metoda rzuca ogólny wyjątek, to niby nie jestem w stanie potem odróżnić jaki to był konkretny wyjątek, bo pakuje wszystko do ogólnego typu Exception. Jednak w kodzie który widać powyżej, jestem w stanie obsłużyć wszystkie 3 moje wyjątki (w zależności jaki sobie podam parametr do metody m() ), pozostałe zwyczaje będą obsługiwane przez ostatnią klauzulę catch(Exception e). Gdzie jest więc problem?

komentarz 15 września 2016 przez niezalogowany

link -> wyjaśnione w odnośnie PHP, ale problem ten sam (musisz trochę poscrollować) ;)

komentarz 15 września 2016 przez rj45 Nowicjusz (120 p.)

Czytałem to. Właściwie to jest napisane tylko tyle

Nie powinno się rzucać całkowicie generycznymi wyjątkami!

i nic to nowego nie wnosi. Jaka jest różnica między sygnaturą metody:

m() throws Exception{}

m() throws IllegalAccessException, InstantiationException, CloneNotSupportedException, NoSuchFieldException{}

Program w obu przypadkach działa tak samo i nie trace żadnych szczegółów na temat rzuconego wyjątku. 

komentarz 15 września 2016 przez niezalogowany
Jeżeli oznaczysz sobie tekstowo różne wyjątki, to dużo łatwiej zorientować się co szwankuje (np. wyświetla Ci się "Problem z API nr. XXX" a nie "XXX" - dużo wygodniejsze). Na pewno ma to też inne wyjaśnienia, ale tu będziesz musiał poczekać na autora wpisu, bo nie znam się na tyle żeby się wypowiadać ;)
komentarz 15 września 2016 przez Comandeer Guru (599,730 p.)

Właściwie to jest napisane tylko tyle

Szczerze? To chyba jednak nie czytałeś…

Napisałem tam cały długi akapit o tym, wraz z przykładem kodu. I jeśli z tego wyciągnąłeś jedynie pierwsze zdanie, no to cóż. 

2 odpowiedzi

+1 głos
odpowiedź 15 września 2016 przez Comandeer Guru (599,730 p.)

Pisałem o tym w kontekście kursu PHP:

Nie powinno się rzucać całkowicie generycznymi wyjątkami! Sam PHP ma sporo wbudowanych typów wyjątków. Już tylko ich używając można napisać bardzo sensowną obsługę błędów z rozróżnianiem ich typów. Obecnie przedstawiony kod błędnie zakłada, że wszystkie wyjątki dotyczą obsługi bazy danych. W przypadku stosowania konkretnych rodzajów wyjątków można konstruować nawet stopniową obsługę wyjątków:

try {
	// Dziwny kod
} catch ( NetException $e ) {
	echo 'Coś z netem';
} catch ( APIException $e ) {
	echo 'Coś z API';
} catch ( Exception $e ) {
	echo 'Coś, ale nie wiem co…';
}

W tego typu kodzie od razu widzimy jaki błąd dostajemy i możemy dzięki temu odpowiednio pokierować dalej działaniami aplikacji.

Dzięki temu zamiast np. kopać się z parsowaniem komunikatu z wyjątku, od razu po jego typie wiesz, co się dzieje i jak należy to obsłużyć. 

komentarz 15 września 2016 przez Comandeer Guru (599,730 p.)
Inny, być może jeszcze ważniejszy, powód to zgodność z SOLID. Tak szczegółowe wyjątki pełnią bowiem jedną, ściśle określoną funkcję – co wynika bezpośrednio z zasady Single Responsibility (Pojedynczej Odpowiedzialności).
komentarz 15 września 2016 przez Surykat Stary wyjadacz (14,760 p.)
Dodałbym jeszcze, że często podczas testowania jednostkowego, oczekujemy, że dane wywołanie funkcji zwróci jakiś konkretny wyjątek, w asercjach można to potem sprawdzić.

O ile jesteście zwolennikami takiego podejścia, są ponoć ludzie którzy piszą kod exception-safe i koniec. :)
0 głosów
odpowiedź 15 września 2016 przez ReksetoDev Gaduła (4,530 p.)
Odpowiedz znajdziesz w tym co tu napisze : Jesli tworzysz obiekt to czemu nie robic Object d = new Object() a tworzysz obiekt na podstawie klasy ktorej potrzebujesz tak samo tu lapiesz to co potrzebujesz

Podobne pytania

0 głosów
1 odpowiedź 501 wizyt
pytanie zadane 9 lipca 2019 w Java przez magicznyukf Początkujący (260 p.)
+1 głos
3 odpowiedzi 925 wizyt
pytanie zadane 27 sierpnia 2017 w Java przez Patryk Moros Początkujący (470 p.)
0 głosów
0 odpowiedzi 92 wizyt
pytanie zadane 25 marca 2019 w PHP przez Q_Nick Mądrala (5,010 p.)

92,453 zapytań

141,262 odpowiedzi

319,088 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...