Rozumiem że chodzi Ci o niespodziewane wyjątki. Z mojego doświadczenia najlepiej zastosować równocześnie 2 podejścia do tego co wyświetlasz na ekranie:
- Ładny komunikat błędu bez żadnych szczegółów implementacyjnych.
- Ładny komunikat + Stacktrace + inne dane które są przydatne do zlokalizowania błędów.
Pierwsze podejście idzie na produkcję. Drugie pozwoli przekazać testerom maks informacji o problemie jaki wystąpił.
Jeżeli chodzi o implementację tego to najlepiej zrobić to interceptorami. Nie wiem jak to się robi czysto w JEE ale w springu jest nawet specjalny bean oznaczony @ControllerAdvice który może przechwytywać wyjątki i zmieniać ustawiać response. Podejrzewam że w tutaj też jest odpowiednik i jego właśnie bym użył.
Jeżeli jednak chodzi o wyjątki których się spodziewasz, to dotąd widziałem 2 podejścia.
- Jeżeli jest to strona www to wyjątek był przechwytywany, dodanie błędów do strony i czasem robione przekierowanie. Jest to dobre rozwiązanie, bo czasem różnie trzeba zbudować wynik.
- W przypadku rest controllera, zwykle rzucałem wyjątek poza niego i łapałem przez interceptor. Tutaj jest prościej bo albo oczekujesz poprawnych danych albo kodu błędu i jakichś informacji, a te mogą powstać po przetłumaczeniu wyjątku. Ogromną zaletą jest uproszeczenie całego przebiegu żądania, bo jeżeli np. użytkownik zażąda obiektu który np. ktoś wcześniej kupił to rzucasz wyjątek i to wszystko. Transakcje same są wycofywane, nie musisz sztucznie wracać do kontrolera i za każdym razem tłumaczyć tego co poleciało na sensowne dane.