A co w przypadku, gdyby w aplikacji byłaby potrzeba zwrócenia różnych kodów błędów/ wiadomości np: Użytkownik o podanym loginie istnieje, niepoprawny format loginu, niepoprawny format hasła, podane hasła się nie zgadzają itd. Nie łatwiej rzucić wyjątkiem, dołożyć jedną warstwę gdzie byłby stworzony odpowiedni Response i zwrócić go w Kontrolerze?
@Aisekai: odpowiedź krótka brzmi nie. Odpowiedź dłuższa poniżej.
Wyjątki służą do obsługi sytuacji wyjątkowych (so obvious). Jednak żaden z podanych przez ciebie przypadków nie jest sytuacją wyjątkową. Co więcej większość sytuacji, gdzie następuje interakcja z użytkownikiem systemu nie powoduje wyjątków. Niepoprawny login, hasło, próba założenia konta za pomocą istniejącego już w bazie emaila to są sytuacje sensowne biznesowo, ale powinny kończyć się czymś co operator białkowy rozumie jako błąd.
Niestety błędy tego rodzaju bardzo szybką stają się tożsame z wyjątkami. W ten sposób powstaje Exception Driven Development, gdzie ścieżka przebiegu programu jest sterowana wyrzucaniem wyjątków.
Drugim źródłem takiego podejścia, na szczęście coraz rzadszym, jest próba przeniesienia mechanizmu przerwań do wysokopoziomowego kodu. W Javie sprzyja temu metoda Thread.interrupt
oraz historyczne zaszłości związane z pisaniem kodu wielowątkowego na niskim poziomie. W takim przypadku wyjątki są stosowane, by obsługiwać sytuacje, które są na poziomie technicznym do przewidzenia i które powinny finalnie informować użytkownika, że jest aplikacja ma np. niespójne dane.
Wyjątki zostawmy dla błędów technicznych np. braku plików konfiguracyjnych.
Jak nie wyjątek to co?
Status, a na poziomie kontrolera np. pattern matching z vavr:
return Match(order).of(
Case($(ord -> ord.alreadyExist()),
Response.Conflict_409
),
Case($(v ->ord.notExist()),
Response.NotFound_404
Case($(), Response.OK_200)
);