← 中文资源

简体中文版本

HTTP 422 Unprocessable Entity — 校验未通过

把 422 Unprocessable Entity 理解为语义校验失败,读取字段错误,并修复负载校验而非传输层。

阅读英文原文

症状

遇到“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 且带字段细节。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。