症状
遇到“HTTP 422 Unprocessable Entity — 校验未通过”时靠猜测只会浪费时间。请按证据排查:先复现症状,再执行针对性诊断,定位根因后修复,并用明确检查验证结果。
可观察到的症状包括:
- API 返回 422 并附带字段错误的 JSON 列表
- 语法合法的 JSON 请求仍被拒绝
- 客户端只显示笼统失败而无字段细节
诊断
先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。
步骤 1
curl -i -X POST https://api.example.com/users -H 'Content-Type: application/json' -d '{"age": -1}'
响应体会指出失败字段与规则,这才是可操作的信息。
步骤 2
grep -rn "z.number\|z.string\|required" src/schemas
把负载与 schema 对比即可看出违反了哪条约束。
常见诱因(按出现频率排序):
- 必填字段缺失或值违反约束(范围、格式、枚举)
- 负载 JSON 结构正确但对端点语义无效
- 跳过了客户端校验,或客户端规则与服务端不一致
根因
422 表示服务端理解了请求及其媒体类型,但所包含的指令未通过语义校验。它区别于 400(格式错误)与 415(媒体类型错误)。
修复
修改负载以满足 schema(补齐必填、修正格式与范围),并把服务端字段错误展示给用户而非笼统失败。
注意:在客户端重复校验规则会与服务端漂移;应以服务端为准。
// server: return structured field errors with 422
app.post('/users', (req, res) => {
const parsed = schema.safeParse(req.body);
if (!parsed.success) {
return res.status(422).json({ errors: parsed.error.issues });
}
// ...create user
});
// client: show field-level errors
if (res.status === 422) showFieldErrors((await res.json()).errors);
验证
提交修正后的负载并确认 2xx;验证非法负载仍返回 422 且带字段细节。
修复后补充一条回归测试,复现原始症状,防止问题再次出现。
这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。