hl-api-changelog/changelogs-v2/2026-05/23_2940_R7-error-response_PR2948.md

4.6 KiB

R7 真测发现 + 修复:网关错误响应规范化(5 项 CRITICAL+HIGH)

服务: hl-gateway + hl-user-service + hl-common-core + hl-common-web(全模块共依赖) PR: #2948 Issue: #2940 日期: 2026-05-23 影响: 🔴 错误响应格式变更 + Result 新增 traceId 字段 + X-Trace-Id 响应头


⚠️ 关键变化(前端 mmg 必读)

1. 🔴 不存在路径返 Result JSON,不再返 HTML 静态页

之前:https://web.test.1814.love:9443/nonexistent-foo → 网关 fallback 漏到前端 vue 静态页(返完整 HTML),API 调用方 JSON.parse 爆 SyntaxError 之后:返 {code: 404, message: "接口不存在: GET /nonexistent-foo", success: false, data: null, traceId: "xxx"}

前端如果有 try/catch 期望 HTML 响应的代码必须改为 JSON 处理

2. 🟢 Result 类新增 traceId 字段(向后兼容)

所有响应(成功 + 错误)的 data 字段同级新增 traceId:

{
  "code": 200,
  "message": "成功",
  "data": {...},
  "success": true,
  "traceId": "a1b2c3d4e5f6g7h8"  // 新增,16 字符短 UUID
}
  • 旧客户端不识别 traceId 字段不影响(忽略未知字段)
  • 新客户端可记录 traceId 用于线上排查问题(给后端报错时附 traceId 加速定位)

3. 🟢 错误响应必含 X-Trace-Id 响应头

HTTP/1.1 200 OK
X-Trace-Id: a1b2c3d4e5f6g7h8
Content-Type: application/json

前端可统一读取(axios interceptor 等)。

4. 🟡 鉴权错误响应规范化

之前:Authorization 缺失 → 网关返手拼 JSON {code:401, message:"Missing or invalid Authorization header"}success 字段 + 英文 之后:返 4 字段全 + 中文 message:

{
  "code": 401,
  "message": "缺少有效的 Authorization 头",
  "success": false,
  "data": null,
  "traceId": "..."
}

5 处中文化:

  • "Missing or invalid Authorization header" → "缺少有效的 Authorization 头"
  • "Invalid token" → "Token 无效"
  • "Token expired or revoked" → "Token 已过期或被撤销"
  • "Unknown token type" → "Token 类型未知"
  • "请使用小程序端接口" 保留

改动概览

1) CRITICAL R7Q-B6 网关 catch-all

  • 新建 GlobalErrorWebExceptionHandler @Order(-2) 优先于 Spring Boot 默认 -1
  • NotFoundException → code=404 + 中文"接口不存在"
  • 上游异常 → code=500/对应 status + 中文

2) HIGH R7Q-B1 JwtAuthFilter

  • 注入 ObjectMapper + 抽 writeErrorResponse(exchange, code, message) 统一写出
  • 5 处 forbidden/unauthorized 改 Result.error(code, message)(自带 success=false)
  • 5 处英文 message 中文化

3) HIGH R7Q-B5 TokenInterceptor

  • 注入 ObjectMapper + writeError(request, response, code, message) 统一
  • 5 处 response.getWriter().write("{...}")objectMapper.writeValueAsString(Result.error(...))

4) HIGH R7Q-B2 NoHandlerFoundException 确认已生效

  • hl-common-log/GlobalExceptionHandler.java:255 已注册
  • hl-common-web/HlMvcDefaultsEnvironmentPostProcessor 已注 spring.mvc.throw-exception-if-no-handler-found=true + spring.web.resources.add-mappings=false

5) HIGH R7Q-B9 X-Trace-Id 全链路

  • Result.java 新增 traceId 字段
  • TraceIdFilter(gateway,@Order(-200))无请求头时生成 16 字符短 UUID + 注入下游请求头 + 响应头
  • TraceIdResponseFilter(hl-common-web)后端服务读请求头 → MDC + 响应头,filter 结束清 MDC 防线程池串数据
  • JwtAuthFilter / TokenInterceptor / GlobalErrorWebExceptionHandler 错误响应同步注入 X-Trace-Id

R7 完整测试覆盖(4 agent)

Agent 维度 发现
R7-N Swagger 三角 71 Controller / 360 端点 / 311 VO / 3095 字段 1 P0(#2880 设计不修)+ 4 P1 + 4 P2,47% 缺 @ApiOperation(留 backlog)
R7-O Long 精度 333 VO 文件 / 440 Long 字段 / 18+ 真测接口 0 BUG(全局 NumberSerializer 完备)
R7-P 序列化 30+ 接口 4 维度 6 bug 全 v2 老代码(留 backlog)
R7-Q 错误响应 57 错误场景 1 CRITICAL + 4 HIGH + 3 MEDIUM + 1 LOW(本工单修 5 项)

测试

20 新单测,5 模块 mvn test 全绿(common-core 484 + common-web 18 + common-log 68 + gateway 11 + user 2486)。

13 文件 +876 -32 lines。

留尾(独立 backlog,本工单不做)

  • R7N 47% 端点缺 @ApiOperation(168/360)
  • R7-P 6 v2 老代码 status/Boolean Integer 化
  • R7-Q MEDIUM 3 项:@Valid 缺字段名 / 415 兜底 500 / enum deserialize 吞异常
  • R7-Q LOW:6 条 ErrorCode 纯英文(ContractErrorCode 3 + SettlementErrorCode 3)

关联

  • 工单 #2940(closed after PR merged)
  • PR #2948(squash merged)
  • R7 4 报告:.tmp/qa-r7{n,o,p,q}-*-report.txt