Пользовательское исключение из обработчика 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();
}