Czy warstwa usługi powinna wychwytywać wszystkie wyjątki dao i owijać je jako wyjątki usługi?

23

Mam trójwarstwową aplikację sieciową Spring: dao, serwis i kontrolery. Kontroler nigdy nie wywołuje bezpośrednio dao, robi to poprzez warstwę usługi. W tej chwili przez większość czasu, jeśli istnieje wyjątek dao (środowisko wykonawcze), który nie jest obsługiwany, zostanie przechwycony przez stronę JSP pokazującą komunikat o błędzie użytkownikowi końcowemu. Czy warstwa usługi powinna wychwytywać wszystkie wyjątki dao i owijać je jako wyjątki usługi?

try {
   daoInstance.someDaoMethod();
} catch(DataAccessException dae) {
   throw new ServiceException("message", dae);
}

Załóżmy, że ServiceException to także środowisko wykonawcze i nie jest obsługiwane. Czy jest jakaś różnica, aby po prostu wygenerować DataAccessException zamiast ServiceException? Pomyślałem, że warstwa prezentacji nie powinna wiedzieć o wyjątku dostępu do danych. Ale nie widzę sensu wychwytywania wyjątków, których nie można odzyskać, tylko po to, by je owinąć.

Oscar
źródło

Odpowiedzi:

18

Myślę, że ważnym czynnikiem jest to, kim są Twoi klienci usług.

Jeśli twoja warstwa usług jest tylko architektoniczną granicą między warstwami w twoim projekcie, a klient usługi znajduje się w tej samej sferze zaufania, wtedy możesz się zrelaksować i pozwolić, aby niezaznaczone wyjątki wyskoczyły na warstwę kontrolera lub klienta usługi.

Jednak w przypadku publicznego kodu; usługa, z której korzysta osoba trzecia lub klient, myślę, że łatwiej jest ominąć wszelkie niesprawdzone wyjątki wyjątkiem zorientowanym na usługi, przede wszystkim ze względów bezpieczeństwa, po drugie z powodu luźnego łączenia i czystej abstrakcji.

Wyjątek warstwy danych nigdy nie powinien bezpośrednio docierać do użytkownika końcowego aplikacji internetowej . Potencjalnie zawiera wewnętrzne informacje o twoim schemacie, twoich zapytaniach, numerach linii, nazwach zmiennych lub funkcji itp. Wyjątki dla użytkowników końcowych mogą zostać zdezynfekowane w bezpiecznym ustawieniu.

Klient usług zewnętrznych nie przejmuje się szczegółami implementacji i i tak nie może obsłużyć niesprawdzonych wyjątków, ponieważ są to błędy lub problemy środowiskowe. W bezpiecznych aplikacjach błędy bazy danych po prostu nie są wystarczająco bezpieczne, aby się rozprzestrzeniać, OracleException - ORA-01234 - ...co może być wstawioną trzecią tabelą. Klient powinien mieć możliwość radzenia sobie ze wszystkimi sprawdzonymi / oczekiwanymi wyjątkami, które może obsłużyć, i traktować wszystko inne jako potencjalny raport o błędzie. Umowa o świadczenie usług powinna być atomową, spójną, transakcyjną abstrakcją. Jeśli nie jest w stanie nic zrobić z wyjątkiem wyjątku, jedyną przydatną rzeczą, która pozostała, jest zgłoszenie błędu. Masz już możliwość zarejestrowania wyjątku, więc po co obciążać użytkownika końcowego szczegółami? Twoja aplikacja może być monitorowana, abyś wiedział o niezaznaczonych wyjątkach, zanim użytkownicy je zgłoszą.

Nigdy nie można jeść wyjątków, nie jestem też fanem sprawdzonych wyjątków, ale wolę mieć plan odpowiedni dla charakteru całego produktu.

codenheim
źródło
13

Nie, nie powinieneś umieszczać wyjątków DAO w aplikacji internetowej

W kodzie jest dużo hałasu, co oznacza zerową korzyść. Nie bez powodu wyjątki DAO są wyjątkami. Kod aplikacji nie może zrobić nic przydatnego w celu odzyskania od wyjątku DAO. Prawdziwy problem jest tutaj:

... zostanie przechwycony przez JSP pokazujący komunikat o błędzie użytkownikowi końcowemu.

Napraw ten problem w jednym miejscu zamiast rozbijać całą bazę kodu.

Kontrolujesz, w jaki sposób nieprzechwycony wyjątek jest wyświetlany użytkownikowi. Nieprzechwycone wyjątki wynikają z błędów aplikacji lub awarii w systemie bazowym. Nie ma powodu, aby przekazywać użytkownikowi jakiekolwiek informacje o tym, dlaczego jego żądanie nie mogło zostać zrealizowane. Użytkownik nic nie może zrobić. Wystarczy, że podasz przyjazną stronę błędów.

Uwaga: jeśli piszesz dużo żmudnego kodu, na przykład tworząc blok bloków, które po prostu owijają się i ponownie rzucają, prawie zawsze istnieje lepsze rozwiązanie.

Kevin Cline
źródło
Dzięki za odpowiedź. I tak, jsp wyświetla niestandardowy komunikat: „Ups, coś poszło nie tak”. Nie pokazuje żadnych informacji o wyjątku
Oscara
7

Głównym powodem zastosowania owijania wyjątków jest uniemożliwienie kodowi w warstwie biznesowej konieczności znajomości każdego możliwego wyjątku w systemie . Istnieją dwa główne powody:

  • Spójność: zadeklarowane wyjątki łączą się w górę stosu wywołań. Jeśli nie zawiniesz wyjątków, ale przekażesz je dalej, deklarując metody ich wyrzucenia, możesz skończyć z metodami najwyższego poziomu, które deklarują wiele różnych wyjątków. Deklarowanie wszystkich tych wyjątków w każdej metodzie w górę stosu wywołań staje się nużące.

  • Hermetyzacja: Możesz nie chcieć, aby komponenty najwyższego poziomu wiedziały coś o komponentach najniższego poziomu, ani o wyjątkach, które zgłaszają. Na przykład, interfejsy i implementacje DAO mają na celu wyodrębnienie szczegółów dostępu do danych z dala od reszty aplikacji. Teraz, jeśli twoje metody DAO rzucają wyjątki SQLException, kod używający DAO będzie musiał je złapać. Co się stanie, jeśli zmienisz się na implementację, która odczytuje dane z usługi internetowej zamiast z bazy danych? Następnie metody DAO będą musiały zgłaszać zarówno wyjątek zdalny, jak i wyjątek SQLException. A jeśli masz DAO, który odczytuje dane z pliku, musisz także zgłosić wyjątek IOException. To trzy różne wyjątki, każdy związany z własną implementacją DAO.

Krótko mówiąc, odpowiedź brzmi tak!

fabienbk
źródło
3
Implementacje JPA (np. Hibernacja) rzucają niesprawdzone wyjątki. Nie trzeba ich deklarować ani łapać.
kevin cline,