Пользовательское исключение из обработчика Messenger

Я пробую версию Symfony 4.3.0-dev, чтобы получить некоторые новые функции из компонента Messenger. Моя командная шина работает в режиме синхронизации.

Перед обновлением я мог легко вернуть свое пользовательское исключение ConflictException из обработчика. Но для 4.3.0-dev я получаю Symfony\Component\Messenger\Exception\HandlerFailedException. Как вернуть мое пользовательское исключение снова?

1 ответ

Начиная с Symfony 4.3, если обработчик генерирует какое-либо исключение, он будет заключен в Symfony\Component\Messenger\Exception\HandlerFailedException.

Это отражено здесь в журнале изменений:

[BC BREAK] Исключение HandlerFailedException будет выдано, если один или несколько обработчиков не сработают.

В местах, где вы имеете дело с синхронным транспортом и хотите иметь дело с исходным исключением, вы можете сделать что-то похожее на то, что делает Api-Platform в этомDispatchTrait:

namespace App\Infrastructure\Messenger;

use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\MessageBusInterface;
use Throwable;

trait DispatchTrait
{

    private ?MessageBusInterface $messageBus;

    /**
     * @param object|Envelope $message
     * @return Envelope
     * @throws Throwable
     */
    private function dispatch($message): ?Envelope
    {
        try {
            return $this->messageBus->dispatch($message);
        } catch (HandlerFailedException $e) {
            while ($e instanceof HandlerFailedException) {
                /** @var Throwable $e */
                $e = $e->getPrevious();
            }

            throw $e;
        }
    }
}

(Эта версия не имеет обратной совместимости и устраняет MessageBus проверьте, так как я использую только для внутренних приложений, которые я контролирую).

В каком бы классе вы ни отправляли свое сообщение, вы могли:

class FooController
{
    use DispatchTrait;

    public function __construct(MessageBusInterface $messageBus) {
        $this->messageBus = $messageBus;
    }

    public function __invoke(Request $request)
    {
        // however you create your message
        $command = Command::fromHttpRequest(); 

        try {
                $this->dispatch($command);
        }
        catch (ConflictException $e) {
            // deal with the original exception
        }
    }
}

Как вы можете видеть на CHANGELOG, разрыв версии BC был представлен в версии 4.3. В моем приложении я ловил исключения, и я решил, добавив следующий код:

if ($exception instanceof HandlerFailedException) {
    $exception = $exception->getPrevious();
}
Другие вопросы по тегам