我尝试使用 Symfony 4.3.0-dev 版本从 Messenger 组件中获取一些新功能。我的命令总线在同步模式下工作。
在升级之前,我可以轻松地ConflictException
从处理程序中抛出我的自定义异常。但是对于 4.3.0-dev 我得到一个Symfony\Component\Messenger\Exception\HandlerFailedException
.
如何再次捕获我的自定义异常?
我尝试使用 Symfony 4.3.0-dev 版本从 Messenger 组件中获取一些新功能。我的命令总线在同步模式下工作。
在升级之前,我可以轻松地ConflictException
从处理程序中抛出我的自定义异常。但是对于 4.3.0-dev 我得到一个Symfony\Component\Messenger\Exception\HandlerFailedException
.
如何再次捕获我的自定义异常?
从 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中看到的,4.3 版中引入了 BC 中断。在我的应用程序中,我正在捕获异常,并通过添加以下代码来解决:
if ($exception instanceof HandlerFailedException) {
$exception = $exception->getPrevious();
}