Автоматическое внедрение зависимости дескриптор исключения Laravel - PullRequest
0 голосов
/ 04 октября 2019

Вот мой случай

У меня есть задание cron (консольная команда)

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle(OrdersMagentoService $magentoService)
    {
        try {
            $orders = $magentoService->getRemoteOrders();
            print_r($orders);
        } catch (SoapFault $e) {
            $this->line('Error connect to soap api, error: ' . $e->getMessage());
            die;
        } catch (\Throwable | \Exception $e) {
            print_r($e->getMessage());
            die;
        }
    }

В методе handle я автоматически внедряю OrdersMagentoService, эта служба подключается к magento soap apiи исключить из BaseMagentoService

class OrdersMagentoService extends BaseMagentoService
{
    public function getRemoteOrders()
    {
        $complex = [
            'complex_filter' => [
                [
                    'key' => 'status',
                    'value' =>
                        [
                            'key' => 'in',
                            'value' => 'closed,canceled,holded,processing,complete'
                        ]
                ],
                [
                    'key' => 'updated_at',
                    'value' => [
                        'key' => 'from',
                        'value' => now()->subDays(200),
                    ]
                ]
            ]
        ];

        return $this->salesOrderList($complex);
    }
}
class BaseMagentoService
{
    /**
     * @var
     */
    private $client;

    /**
     * @var
     */
    private $session;

    /**
     * @var \Illuminate\Config\Repository|mixed
     */
    protected $config;

    /**
     * BaseMagentoService constructor.
     */
    public function __construct()
    {
        $this->config = config('services.magento');
        $this->connect();
    }

    /**
     * Do connect to soap api v2
     *
     * @throws \SoapFault
     */
    private function connect()
    {
        $this->client = new SoapClient($this->getApiUrl());
        $this->session = $this->client->login($this->config['user_name'], $this->config['password']);
    }

    public function __call($resource, $arguments)
    {
        return $this->client->$resource($this->session, ...$arguments);
    }
}

В конструкторе BaseMagentoService я создаю соединение с magento soap api. Но если ошибка соединения (например, неверное имя пользователя и пароль), я не могу обработать это в файле задания cron. Я понимаю, что laravel сначала создает OrdersMagentoService, он выдает ошибку и try catch в handle функция не работает, но я не знаю, как это исправить.

Я могу добавить в handle метод

        try {
            $magentoService = resolve(OrdersMagentoService::class)
            $orders = $magentoService->getRemoteOrders();
            print_r($orders);
        } catch (SoapFault $e) {
            $this->line('Error connect to soap api, error: ' . $e->getMessage());
            die;
        } catch (\Throwable | \Exception $e) {
            print_r($e->getMessage());
            die;
        }

И удалить автоматический DI, и синица должна работать хорошо, но я не хочу этого делать.

Также, если я добавлю try catch в connect метод BaseMagentoServiceтогда я не могу записать эту ошибку в мою работу cron.

Какой лучший способ справиться с этим?

1 Ответ

1 голос
/ 05 октября 2019

Сначала я бы переключил обработку с команды ремесленника на задание или событие, которое могло бы больше соответствовать проблеме. Затем ваша команда ремесленника просто запускает это новое задание или событие каждый раз, когда выполняется.

Это также как-то указано в документации как лучшая практика:

Для большего повторного использования кода,Хорошей практикой является поддерживать команды консоли легкими и позволять им обращаться к службам приложений для выполнения своих задач.

Тогда, если вы посмотрите документацию о заданиях, есть раздел об обработке ошибок для сбойных функций. заданий, где вам говорят, что вы можете определить метод, который запускается после сбоя задания. Пример выдержки из документации:

class YourJob implements ShouldQueue
{
    /**
     * Execute the job.
     *
     * @param  AudioProcessor  $processor
     * @return void
     */
    public function handle(AudioProcessor $processor)
    {
        // Process uploaded podcast...
    }

    /**
     * The job failed to process.
     *
     * @param  Exception  $exception
     * @return void
     */
    public function failed(Exception $exception)
    {
        // Send user notification of failure, etc...
    }
}

Подробнее о вы можете прочитать в документации . Также есть параграф об обработке глобальных сбоев заданий, который может подойти вашему сценарию использования

...