3

我尝试使用 Symfony 4.3.0-dev 版本从 Messenger 组件中获取一些新功能。我的命令总线在同步模式下工作。

在升级之前,我可以轻松地ConflictException从处理程序中抛出我的自定义异常。但是对于 4.3.0-dev 我得到一个Symfony\Component\Messenger\Exception\HandlerFailedException.

如何再次捕获我的自定义异常?

4

2 回答 2

3

从 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
        }
    }
}
于 2019-12-30T17:33:24.963 回答
2

正如您在CHANGELOG中看到的,4.3 版中引入了 BC 中断。在我的应用程序中,我正在捕获异常,并通过添加以下代码来解决:

if ($exception instanceof HandlerFailedException) {
    $exception = $exception->getPrevious();
}
于 2019-05-30T16:24:45.447 回答