Я прочитал здесь несколько ответов об обмене стеками, но ни один из них действительно не «попадает в точку» о том, где бросать исключения, где не следует и где их ловить.
идея о том, что исключение должно генерироваться в исключительных случаях, очень расплывчата, например, если я не могу найти пользователя в моем источнике данных (репозитории), я не могу продолжить выполнение своего кода, может ли это считаться исключительным?
Я также понимаю, что есть предостережения по поводу управления потоком с исключениями, для меня не кажется правильным использовать try / catch внутри службы, чтобы уловить все исключения, которые репозиторий / адаптер / что-то может вызвать, чтобы контролировать, что делать дальше.
на основе этого пример кода с «службой» и контроллером, вызывающим службу и перехватывающим все исключения службы:
Услуга:
class CheckUserUltraSecretInformation
{
public function __construct(
private CachedUserDataRepository $cachedDataRepository,
)
{
}
public function handle(string $document)
{
$cachedUserData = $this->cachedDataRepository->findByDocument($document);
if (empty($cachedUserData)) {
throw new CachedUserDataNotFoundException('User Cached information not found, cannot proceed');
}
if ($cachedUserData->hasExpired()) {
throw new CachedUserDataHasExpiredException('Cached user data is expired');
}
// return ultra secret information
}
}
Контроллер:
class UserSecretInformationController
{
public function __construct(
private CheckUserUltraSecretInformation $checkUserUltraSecretInformation)
{
}
public function checkUserInformation(Request $request)
{
$document = $request->input('document');
try {
$userUltraSecretInformation = $this->checkUserUltraSecretInformation->handle($document);
} catch (CachedUserDataNotFoundException $exception) {
// return json response with http code 400
} catch (CachedUserDataExpiredException $exception) {
//returns json response with http code 500
}
}
}
«Правильно», что мой репозиторий не генерирует исключения, а только возвращает
null/false
когда он не может вернуть сущность? если нет, то в чем проблема?если мой репозиторий выдает исключения, должна ли моя служба их фиксировать и повторно запускать как исключения службы? это считается управлением потоком?
Являются ли внешние слои «наиболее правильными» для захвата и обработки исключений? в моем примере используется контроллер. Может ли он знать имя исключений служб / вариантов использования?