W sumie temat trochę z pogranicza designu aplikacji, więc może nie najlepszy dział wybrałem, aczkolwiek korzystam z Javy i Springa, tak więc jakieś technologiczne ograniczenia na pewno też wchodzą w grę.
Jako pracę inżynierską projektuję, implementuję i wdrażam aplikację. Z grubsza, jest to trochę przerośnięty CRUD, w środku siedzi jednak trochę dodatkowej logiki. Obecnie pracuję nad backendem, docelowo jednak powstanie również frontend, korzystający z API wystawionego przez wspomniany backend.
No i zastanawiam się jak rozwiązać obsługę błędów. Obecnie próbuje podejście, w którym wydzieliłem 3 kategorie błędów
constraintViolations
- wszelkie błędy typu "to pole nie może być nullem", generalnie mógłbym tutaj zakończyć pracę na dodaniu adnotacji@NotNull
na wejściowych DTOsach i w controllerach dorzucić@Valid @RequestBody
. Spring sam ogarnie co z tym zrobić, jednak jako że chciałbym mieć jeden spójnyErrorResponse
dla wszystkich przypadków, to po prostu samemu będę wołać te walidację w jakimś interceptorze i mapować to na swoje błędy.domainError
- wszelkie błędy, które wyszły z serwisu (ale nie wyjątki). Korzystam z vavrowegoEither
i każdy serwis który robi jakąś logikę ma po lewej stronie listę enumów opisujacych kolejno co poszło nie tak.exception
- czyli wszystko co faktycznie sypnie wyjątkiem i zmapuje się na HTTP 500, czyli jakiś błąd z bazy danych czy niedostępność zewnętrznego API które wołam w aplikacji. Łapie taki wyjątek w@ControllerAdvice
i wrzucam doexception
opisanego poniżej.
No i to wszystko opakowałem w coś takiego
@Getter
public class ErrorResponse {
private final List<ConstraintViolation> constraintViolations;
private final List<DomainError> domainErrors;
private final ExceptionWrapper exception;
// static factories
}
No i zastanawiam się jak to najlepiej obsłużyć na UI
- Http 5xx -> redirect na stronę z informacją "coś poszło nie tak, spróbuj ponownie później". Na dobrą sprawę, ten
exception
mi w response nie jest aż tak potrzebny z punktu widzenia klienta - Http 401/403 -> redirect do logowania
- Http 400 -> czyli jakiś
constraintViolation
, wiem wtedy że muszę szukać w tym miejscu i jakoś to wyświetlić. Frontend jednak będzie mimo wszystko mieć walidację na formularzach, jak zostawię pustę poleemail
to od razu lepiej mieć o tym informację, a nie dostawać ją dopiero z backendu. - Http 409 -> tutaj chciałbym wrzucić wszystkie błędy z domeny, nie wiem czy jest na to lepszy status, w każdym razie, wszystko co się tu nie uda powinno jakoś zostać przedstawione użytkownikowi.
Pytanie jednak, czy jest sens bawić się w robienie jednolitego ErrorResponse
? Może wystarczy, żebym zwrócił domainError
który ma jakieś znaczenie na UI i nie może być tam wcześniej walidowany i do tego włączyć @Valid
na requestach w controllerach i tyle, nie przejmować się tym podwójnie, skoro i tak muszę to obsłużyć na frontendzie zanim wyślę request?