我正在研究基于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_listener
和http_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);
}
}
我非常感谢您提供任何帮助或想法来为该问题找到正确的解决方案。谢谢!