symfony默认html错误页不适用于api,必须通过kernel.exception事件监听并按accept头判断是否返回json响应,否则会向前端app返回html页面;不能用控制器try-catch,否则破坏http语义异常转换、丢失响应头与校验细节。

直接上结论:Symfony 默认的 HTML 错误页对 API 完全不可用,必须拦截 kernel.exception 事件,只对 Accept: application/json 请求做 JSON 化处理,否则会把登录页或 404 页面塞给前端 App。
为什么不能在控制器里 try-catch 每个异常
手动捕获会绕过 Symfony 内核的异常处理链,导致三类问题:
-
AccessDeniedException不再自动转成 403,NotFoundHttpException不再带标准X-Content-Type-Options头 - 无法复用
Serializer统一字段结构(比如始终带error.code和error.message) - ValidationException 等校验异常丢失
violations细节,只能返回笼统的 “Bad Request”
如何注册一个只处理 JSON 请求的异常监听器
核心是检查请求头,不是所有异常都该转 JSON —— 比如管理员访问 /admin 触发 403,不该返回 JSON 而该跳登录页。
- 监听
kernel.exception事件,在服务配置中绑定ApiExceptionListener - 在监听器中调用
$request->getAcceptableContentTypes(),用in_array('application/json', ...)判断是否应 JSON 化 - 对
ValidationFailedException提取$e->getViolations(),生成带property_path和message的嵌套数组 - 对
AccessDeniedException或NotFoundHttpException直接映射为 403/404 状态码,不抛新异常
public function onKernelException(ExceptionEvent $event): void
{
$request = $event->getRequest();
if (!in_array('application/json', $request->getAcceptableContentTypes(), true)) {
return;
}
$exception = $event->getThrowable();
$response = match (true) {
$exception instanceof ValidationFailedException => $this->buildValidationResponse($exception),
$exception instanceof AccessDeniedException => new JsonResponse(['error' => 'forbidden'], 403),
default => new JsonResponse(['error' => 'internal_error'], 500),
};
$event->setResponse($response);
}
如何让异常响应和正常 $this->json() 保持字段一致
关键点是复用同一个序列化上下文,避免两套逻辑维护不同结构。不要手拼数组,而是统一走 SerializerInterface。
- 定义一个序列化组,比如
error:api,并在错误数据对象上用#[Groups(['error:api'])]标记字段 - 监听器中构造错误对象(非数组),例如
new ApiErrorResponse($code, $message, $details) - 调用
$this->serializer->serialize($error, 'json', ['groups' => 'error:api'])输出 - 这样
ApiErrorResponse类就能控制哪些字段出现、是否驼峰、是否默认值,和实体序列化完全一致
最容易被忽略的是 Accept 头解析逻辑 —— $request->headers->get('Accept') 返回原始字符串,需用 getAcceptableContentTypes() 才能正确处理 application/json, text/plain;q=0.5 这类带质量因子的值。漏掉这点,某些 Postman 或 curl 请求就会意外返回 HTML 错误页。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











