S
S
SM_ST2022-03-30 16:06:49
PHP
SM_ST, 2022-03-30 16:06:49

Laravel Service Layer error handling?

How to properly organize the service layer in order to catch errors and reuse them in the future?

controller

public function store(RetailProductCreateService $productCreateService, RetailProductCreateRequest $request)
    {
        $retail = Retail::getRetailStoreIdByCompanyId(50);

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

service
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();
        }
    }
}

I thought to do return false in catch, but I can’t hint at the type of error, for example, if there is such an entry (in validation, it’s not an option to do unique slug )

then I thought to do return throw new .... , but it’s also wrong for the service to immediately shoot out the answer

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
pLavrenov, 2022-03-30
@pLavrenov

sentry.io - try this service and forget about error tracking Installation
--------
Exceptions raise an event and you can implement your own logic in the listener of this event. No return throw needed

F
FanatPHP, 2022-03-30
@FanatPHP

in catch, you need to check the type of the error.
if it's a "there is such a record" error, then throw an exception that will be understood by the controller and converted to a custom error
; if it's any other error, then just throw $e;

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

and then later in the controller it will be possible
try {
    $productCreateService->store($retail->id, $request->getDto());
}catch(NonUniqueValueException $e){
    // пишем юзеру
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question