第三方接口调用失败时,不应直接返回404给前端,而应根据实际原因转换为503等语义准确的状态码,并返回application/json格式的结构化错误响应。

第三方接口调用失败时,不建议直接返回 404 页面给前端 API 客户端——这会混淆语义:404 表示“资源不存在”,而实际是“上游服务不可用”。正确做法是区分场景,按 HTTP 状态码与响应格式规范处理。
明确失败类型再决定响应方式
调用百度等已下线接口(如 api.map.baidu.com/telematics/v3/weather)时,常见响应是 error_code:20 或 HTTP 404。这不是你路由没配好,而是后端服务已停运多年。此时应主动捕获异常,避免把错误透传给前端。
- 用
curl或file_get_contents发起请求后,检查返回状态码和 body 内容 - 若响应含
"error_code":20或空 JSON / 404 HTTP 状态,说明上游已不可用,应转为业务层 503(Service Unavailable)或自定义错误 - 不要让前端收到 404 并误以为“请求路径写错了”
统一异常监听器中拦截并转换
Symfony2 不支持现代异常处理器语法,需手动注册 kernel.exception 监听器,并只对 Accept: application/json 请求做 JSON 响应转换:
- 在监听器中判断
$request->getAcceptableContentTypes()是否包含application/json - 对网络请求失败(如 cURL error、超时、空响应),抛出自定义
UpstreamUnavailableException - 在
onKernelException中匹配该异常,返回JsonResponse(['error' => 'upstream_service_down'], 503) - 避免使用控制器内
try-catch,否则丢失 Symfony 的异常链和标准响应头
代理接口路由需显式声明失败兜底
你对外暴露的代理路由(如 /api/weather)应独立承担错误责任:
- 控制器中调用第三方接口前,可加轻量健康检查(如 ping 接口域名或缓存最近一次成功时间)
- 若确认不可用,直接返回
$this->json(['message' => '天气服务暂不可用'], 503) - 不要依赖 Symfony 默认 404 页面——那是为 HTML 请求准备的,API 场景下会返回 HTML 内容,前端无法解析
- 确保响应 Content-Type 是
application/json,且状态码语义准确
生产环境禁用“伪404”跳转逻辑
有些开发者会在第三方失败时重定向到一个前端页面(如 /error/external),这对纯 API 项目毫无意义:
- 移动端或 JS 前端收到 302 重定向,通常不会自动跳转,只会报 CORS 或跨域失败
- 若真需展示友好提示,应由前端根据 503 响应自行渲染降级 UI
- 后端唯一职责是提供结构化、语义清晰的 JSON 错误响应,不参与视图跳转


















