You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Symfony 5.4自定义错误控制器如何访问闪存消息或传递信息?

解决Symfony 5.4自定义错误控制器无法访问闪存消息的问题

问题原因

当你在控制器中抛出异常后,Symfony会启动一个子请求来调用自定义错误控制器。这个子请求会初始化全新的会话实例,导致无法直接获取父请求中设置的闪存消息。


解决方案一:自定义异常携带额外信息

既然闪存消息是用来传递额外提示,不如直接把信息封装到自定义异常中,跳过闪存的限制:

  1. 创建自定义异常类
// src/Exception/CustomBadRequestException.php
namespace App\Exception;

use Symfony\Component\HttpKernel\Exception\BadRequestException;

class CustomBadRequestException extends BadRequestException
{
    private $suggestion;

    public function __construct(string $message, string $suggestion, int $code = 0, \Throwable $previous = null)
    {
        parent::__construct($message, $code, $previous);
        $this->suggestion = $suggestion;
    }

    public function getSuggestion(): string
    {
        return $this->suggestion;
    }
}
  1. 在HomeController中抛出自定义异常
// HomeController中的代码
// 移除原闪存设置代码,直接用异常传递信息
throw new CustomBadRequestException("error.bad.request.accueil", 'This is a test');
  1. 在ErrorController中读取信息
public function show(\Throwable $exception, Request $request): Response
{
    $suggestion = '';
    if ($exception instanceof \App\Exception\CustomBadRequestException) {
        $suggestion = $exception->getSuggestion();
    }

    return $this->render("commonoffice/error/test.html.twig", [
        'exception' => $exception,
        'suggestion' => $suggestion
    ]);
}

解决方案二:通过Kernel事件传递闪存消息

如果一定要用闪存机制,可以借助kernel.exception事件,在子请求启动前把闪存消息转移到可访问的位置:

  1. 创建事件订阅者
// src/EventSubscriber/ExceptionFlashTransferSubscriber.php
namespace App\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;

class ExceptionFlashTransferSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ExceptionEvent::class => 'onKernelException',
        ];
    }

    public function onKernelException(ExceptionEvent $event): void
    {
        $request = $event->getRequest();
        $flashBag = $request->getSession()->getFlashBag();

        // 将闪存消息转存到会话的普通属性(非一次性)
        if (!$flashBag->isEmpty()) {
            $request->getSession()->set('error_flash_data', $flashBag->all());
            $flashBag->clear();
        }
    }
}
  1. 在ErrorController中读取转存的消息
public function show(\Throwable $exception, Request $request): Response
{
    $flashMessages = $request->getSession()->get('error_flash_data', []);
    // 用完后删除避免后续请求重复显示
    $request->getSession()->remove('error_flash_data');

    return $this->render("commonoffice/error/test.html.twig", [
        'exception' => $exception,
        'flash_messages' => $flashMessages
    ]);
}

内容的提问来源于stack exchange,提问作者user19525065

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:07:32