Usługa raczej powinna rzucać wyjątki dotyczące tego co robi, np. brak połączenia z bazą – wyjątek NoDBConnectionException lub podobny. Warstwa HTTP to nie jest coś, czym powinna się zajmować usługa.
Dodatkowo wyjątki powinny dotyczyć – jak sama nazwa sugeruje – sytuacji wyjątkowych. Owszem, można wszelkie błędy obsługiwać przy pomocy wyjątków, ale wówczas w kontrolerze narośnie nam wiele bloków try/catch obsługujących poszczególne rzeczy. W tym wypadku zwróciłbym po prostu informację, że rekord nie został dodany, z opcjonalną informacją czemu. Innymi słowy: wyjątki zostawiłbym dla błędów niezależnych od naszego kodu (brak połączenia z bazą, niemożność zapisu do pliku itd.), a błędy związane bezpośrednio z działaniem aplikacji czy błędnie wprowadzonymi przez użytkownika danymi (a zatem błędami, o których użytkownik powinien się dowiedzieć) obsługiwałbym "normalnie".
Ogólnie to widziałbym to jakoś tak:
<?php
public function handleRequest( $req ) {
try {
if ( !$this->myService->saveToDB( $req ) ) {
// Nie zapisano, trzeba wyświetlić błąd użytkownikowi.
}
} catch( Exception $e ) {
// Baza się krzakła.
throw new HTTPException( 500 );
}
}
W sumie tutaj jest fajny artykuł opisujący dokładniej to, o czym napisałem: http://adam.wroclaw.pl/2015/05/wyjatki-kiedy-jak-i-po-co/
Oczywiście można też stosować podejście zupełnie odwrotne: https://zawarstwaabstrakcji.pl/20170309-walidacja-w-architekturze-wielowarstwowej/ – pytanie, na ile chcemy komplikować całość.