Łukasz D.

Łukasz D. Software Developer,
DevOps Fan

Temat: Rzucanie wyjątków w serwisach

Witam

Tak sobie się zastanawiam, czy jeśli jakaś operacja nie powiedzie się w metodzie serwisowej, to rzucać wyjątek na zewnątrz, który będzie łapany np. w kontrolerze, czy też może zwracać np. null przy nie udanym zapisie obiektu do bazy danych, tak jak to robią domyślnie metody save() i update() w klasach domenowych w Grailsach?

Jak ogólnie zarządzacie wyjątkami w waszych aplikacjach?
Paweł Grzegorz Kwiatkowski

Paweł Grzegorz Kwiatkowski Architekt
oprogramowania,
Ericsson

Temat: Rzucanie wyjątków w serwisach

Pewnie ilu programistów tyle opinii :)

W nowej aplikacji (tj. projektowanej od 0) staram się mieć własną hierarchię wyjątków, łapać wyjątki "techniczne" (np. SQL error: NO_DATA_FOUND ) logować informację o problemie i zwracać wyjątki "biznesowe" (CustomerNotFoundException), które można pokazać użytkownikowi aplikacji.

Oczywiście dużo zależy od modelu przetwarzania danych w aplikacji, modelu transakcyjnego i pewnie paru innych czynników, np. istniejący projekt aplikacji i wpasowanie się w istniejący model obsługi zdarzeń szczególnych.

A zwracać null czy nie zwracać? Co zwracać w przypadku sukcesu? Jak klient ma interpretować zwracane obiekty?

W przypadku hierarchii wyjątków sprawa wydaje mi się prostsza, publikuję interfejs, klient wie, ze może spodziewać się wyjątku "BiznesException". A ja mogę rzucać MyBiznesException1, MyBiznesException2 dziedziczone z BiznesException i mieć dowolną granulację, co więcej będzie to niejako przezroczyste dla klienta.

A co w przypadku obiektu ? Klient wie, ze dostanie NULL przy porażce z powodu A i coś innego przy sukcesie? A jak oznaczyć porażkę z powodu B ? Można zwracać różne statusy, ale wtedy brniemy w konstrukcje if/else/case etc. Nie korzystamy z mechanizmów obiektowości, kod staje się mniej przejrzysty.
Maciej Nowicki

Maciej Nowicki Java Developer

Temat: Rzucanie wyjątków w serwisach

Nigdy, przenigdy null - zawsze wcześniej czy później gdzieś wymknie ci się spod kontroli i będziesz miał NPE. Jeżeli już to jakiś NullObject.

Osobiście preferuję wyrzucić jakiś własny checked exception, na który tłumaczę sobie ewentualne wyjątki jakie napotkam w metodzie serwisowej.
Łukasz D.

Łukasz D. Software Developer,
DevOps Fan

Temat: Rzucanie wyjątków w serwisach

Zgadzam się z Wami. Mi też bardziej odpowiada rzucanie wyjątków, ale tak zacząłem zastanawiać się nad tym podczas pracy z Grailsami, gdzie nie lecą wyjątki przy walidacji a po prostu null. Widać, że to jednak nieprzemyślana decyzja twórców tego frameworka. Trochę tylko drażni mnie ten delikatny rozdźwięk, między tym jak działają Grailsy a moja warstwa serwisowa ;)

konto usunięte

Temat: Rzucanie wyjątków w serwisach

Maciej Nowicki:

Osobiście preferuję wyrzucić jakiś własny checked exception, na który tłumaczę sobie ewentualne wyjątki jakie napotkam w metodzie serwisowej.

Z checked exception osobiście bym zrezygnował gdzie tylko można, gdyż wiążą one niepotrzebnie implementację z interfejsem a do tego zmuszają do pisania często zbędnie bardziej złożonego kodu.

pzdr

konto usunięte

Temat: Rzucanie wyjątków w serwisach

Łukasz Dziedziul:
Zgadzam się z Wami. Mi też bardziej odpowiada rzucanie wyjątków, ale tak zacząłem zastanawiać się nad tym podczas pracy z Grailsami, gdzie nie lecą wyjątki przy walidacji a po prostu null. Widać, że to jednak nieprzemyślana decyzja twórców tego frameworka. Trochę tylko drażni mnie ten delikatny rozdźwięk, między tym jak działają Grailsy a moja warstwa serwisowa ;)

Możesz użyć failOnError przy zapisie i wtedy poleci grails.validation.ValidationException w przypadku błędu.
book.save(failOnError:true) 

Zostało dodane w Grails 1.2 właśnie z myślą o użyciu w serwisach. Wyjątek dziedziczy po Runtime java.lang.RuntimeException, więc jeśli serwis jest transakcyjny to nastąpi rollback.
Łukasz D.

Łukasz D. Software Developer,
DevOps Fan

Temat: Rzucanie wyjątków w serwisach

Jakub Piasecki:
Możesz użyć failOnError przy zapisie i wtedy poleci grails.validation.ValidationException w przypadku błędu.
book.save(failOnError:true) 

Zostało dodane w Grails 1.2 właśnie z myślą o użyciu w serwisach. Wyjątek dziedziczy po Runtime java.lang.RuntimeException, więc jeśli serwis jest transakcyjny to nastąpi rollback.

Niestety jestem uwiązany do wersji 1.1 :-(
Aleksander Lech

Aleksander Lech Architekt rozwiązań

Temat: Rzucanie wyjątków w serwisach

Zgadzam się z tym, że przenigdy zwracać null (to nie C++, tu wyjątki stosuje się naturalnie). Polecam Ci kolego rozważyć następującą hierarchię wyjątków:

* ApplicationException extends Exception - baza dla wyjatkow biznesowych (checked), np: CustomerNotFoundException, NotEnoughMoneyException.

* SystemException extends RuntimeException - baza/wrapper dla wszelkiego typu wyjaktow technicznych po stronie serwera.



Wyślij zaproszenie do