Symfony 4:将其他异常数据获取到模板

时间:2019-04-10 15:14:48

标签: php symfony exception twig fosrestbundle

我正在研究基于Symfony + FOSRestBundle的REST API。我已经实现了(扩展的)自定义HttpException类,该类将在发生验证错误的情况下使用。沿着错误消息,我总是传递一个数组,其中包含由验证器类生成的有关验证问题的详细数据。这基本上就是我扩展基本HttpException的原因。我的想法是显示从异常到API最终用户的错误数组,但是使用Symfony的核心功能,我总是会收到JSON格式的“ 400 Bad Request”错误(无法在状态代码和信息)。我开始寻找如何克服这个问题的方法,并尝试了各种原理(规范化程序,侦听器...),这些原理是我在网上搜索后发现的,但是这些原理都没有真正解决显示沿代码和消息的错误数组的问题。 / p>

我正在使用Twig生成响应(我喜欢开发模式下的详细HTML错误,因此我无法用其他方法替换它)。我检查了抛出异常时HTTP内核如何处理请求,发现所有内容都通过异常侦听器传递给异常控制器。我创建了自定义异常控制器,并尝试从异常中获取错误数组。但是,实际的异常被包装到FlattenException中,该异常会丢弃该数组。这里的主要问题实际上是FlattenException对象,因为我无法从其中获取有关错误的数据(我知道为什么在那里使用了flatten异常,但是在我的情况下,由于我拥有真正的数组,它并没有真正的用处,而不是一些活动对象)。

我想以某种方式用我的自定义类替换FlattenException-我想要扩展它,以便为消息数组提供另一个属性,该属性将保留到异常控制器的showAction和视图模板呈现之前。然后,我将使用其他逻辑更改静态create函数,以处理包装自定义异常类型时的情况。我不确定在不更改Symfony核心代码的情况下是否有可能,并且如果可能的话,我想避免任何黑客攻击。

我正在考虑的另一件事是扩展/替换ExceptionListener。在那里,我只是更改现有逻辑,以将FlattenException替换为MyCustomFlattenException,然后将其通过ExceptionController方法传递给我的showAction。我已经尝试过并覆盖twig.exception_listenerhttp_exception_listener服务(分别是-一次是第一次,另一次是第二次;我在services.yaml中做了),但是没有太多祝你好运。

对于twig.exception_listener,这就是我的服务……

twig.exception_listener:
  class: App\EventListener\ApiExceptionListener
  arguments:
    $controller: "%twig.exception_listener.controller%"
    $logger: "logger"
  tags:
    - name: kernel.event_subscriber
    - name: monolog.logger
      channel: request

...,我总是收到此错误:

Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\RuntimeException: Cannot autowire service "App\EventListener\ApiExceptionListener": argument "$controller" of method "Symfony\Component\HttpKernel\EventListener\ExceptionListener::__construct()" has no type-hint, you should configure its value explicitly. in /project/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php on line 54

http_exception_listener服务时,这就是我的服务...

http_exception_listener:
  class: App\EventListener\ApiExceptionListener
  arguments:
    [
      null,
      null,
      "%kernel.debug%",
      "%kernel.charset%",
      "%debug.file_link_format%",
    ]
  tags:
    - name: kernel.event_listener
      event: kernel.exception
      method: onKernelException
      priority: -1024
    - name: kernel.reset
      method: reset

...并且没有任何错误,但是仍然调用核心ExceptionListener而不是我在服务中指定的那个。

这是ApiExceptionListener类,在我的IDE中有一些断点可以检查它是否真的被调用:

<?php

namespace App\EventListener;

use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;

class ApiExceptionListener extends ExceptionListener
{
    public function onKernelException(GetResponseForExceptionEvent $event)
    {
        $test = 'ok';
    }

    protected function duplicateRequest(\Exception $exception, Request $request)
    {
        parent::duplicateRequest($exception, $request);
    }
}

我非常感谢您提供任何帮助或想法来为该问题找到正确的解决方案。谢谢!

0 个答案:

没有答案