@SM_ST

Laravel Service Layer обработка ошибок?

Как правильно организовать сервисный слой, чтобы отлавливать ошибки и переиспользовать в дальнейшем?

контроллер
public function store(RetailProductCreateService $productCreateService, RetailProductCreateRequest $request)
    {
        $retail = Retail::getRetailStoreIdByCompanyId(50);

        $productCreateService->store($retail->id, $request->getDto());
    }

сервис
class ProductCreateService
{
    public function __construct(
        private ProductImageService $productImageService,
    ) {
    }

    public function store(ProductCreateDto $dto)
    {
        DB::beginTransaction();

        try {
            $product = new Product();
            $product->category_id = $dto->getCategoryId();
            $product->name = $dto->getName();
            $product->description = $dto->getDescription();
            $product->meta_title = $dto->getMetaTitle();
            $product->meta_description = $dto->getMetaDescription();
            $product->text = $dto->getText();
            $product->slug = $dto->getSlug();
            $product->price = $dto->getPrice();
            $product->old_price = $dto->getOldPrice();
            $product->competitor_prices = $dto->getCompetitorPrices();
            $product->consist = $dto->getConsist();
            $product->settings = $dto->getSettings();
            $product->is_published = $dto->getIsPublished();
            $product->is_accounting = $dto->getIsAccounting();

            $product->saveOrFail();

            $images = $this->productImageService->storeProductImages($product->id, $dto->getImages());

            if ($images) {
                $product->path = $images[0]['path'];
                $product->image = $images[0]['image'];
                $product->saveOrFail();
            }
            DB::commit();

            return true;
        } catch (QueryException $e) {
            DB::rollBack();
        }
    }
}

Думал в catch делать return false, но не смогу намекнуть на тип ошибки, например если такая запись есть (в валидации не вариант делать unique slug )

потом думал сделать return throw new .... , но тоже неправильно и сервиса выпуливать сразу ответ
  • Вопрос задан
  • 237 просмотров
Пригласить эксперта
Ответы на вопрос 2
pLavrenov
@pLavrenov
Разработка сайтов
sentry.io - попробуй этот сервис и забудь про отслеживание ошибок Установка
--------
Исключения вызывают событие и в слушателе этого события можно реализовать свою логику. Не нужно никаких return throw
Ответ написан
FanatPHP
@FanatPHP
Чебуратор тега РНР
в catch надо проверить тип ошибки.
если это ошибка "такая запись есть", то кинуть исключение, которое будет понято контроллером, и преобразуется в пользовательскую ошибку
если это любая другая ошибка, то просто throw $e;

} catch (QueryException $e) {
    DB::rollBack();
    if (условие по которому видно что запись уже есть) {
        throw new NonUniqueValueException(); 
    } else {
        throw $e;
    }
}

и тогда потом в контроллере можно будет
try {
    $productCreateService->store($retail->id, $request->getDto());
}catch(NonUniqueValueException $e){
    // пишем юзеру
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы