Symfony 6.2 API异常监听:HttpException抛出后仍返回200状态码求助
问题解决:Symfony 6.2 ExceptionListener响应状态码始终返回200
问题根源
你的ExceptionListener同时实现了EventSubscriberInterface接口,又在service.yaml中配置了kernel.event_listener标签,这会导致事件被重复订阅。Symfony的事件机制中,重复订阅的监听器可能触发多次,或是后续的监听器(包括框架默认异常处理器)覆盖了你设置的响应状态码,最终返回200。
解决方案(二选一即可)
方案1:移除service.yaml中的事件监听器标签
实现EventSubscriberInterface的类会被Symfony自动扫描并注册为事件订阅者,无需额外配置标签:
修改service.yaml,删除对应标签配置:
App\EventListener\ExceptionListener: # 移除以下标签配置 # tags: # - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }
方案2:移除类中的EventSubscriberInterface实现
如果更倾向于用yaml配置事件监听器,删除类里的接口实现和getSubscribedEvents方法:
// 移除EventSubscriberInterface接口 class ExceptionListener // implements EventSubscriberInterface { public function onKernelException(ExceptionEvent $event): void { // 原有逻辑保持不变 $exception = $event->getThrowable(); $message = sprintf( 'My Error says: %s with code: %s', $exception->getMessage(), $exception->getCode() ); $response = new JsonResponse(['error' => $message]); if ($exception instanceof HttpExceptionInterface) { $response->setStatusCode($exception->getStatusCode()); $response->headers->set('X-Status-Code', $exception->getStatusCode()); $response->headers->replace($exception->getHeaders()); } else { $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); } $event->setResponse($response); } // 移除getSubscribedEvents方法 // public static function getSubscribedEvents() // { // return [ // KernelEvents::EXCEPTION => ['onKernelException', 256], // ]; // } }
额外检查
如果以上方案无效,检查是否有更高优先级的异常监听器(优先级数值大于256)在你之后修改了响应状态码,可以调整监听器优先级确保你的逻辑最后执行。
内容的提问来源于stack exchange,提问作者Paolo Rabbito
相关产品推荐
相关产品推荐

