refactor(api): 请求体解析收成 readJson / parseBody

54 处 handler 都手写同一段:
  const parsed = X.safeParse(await c.req.json().catch(() => null))
  if (!parsed.success) return failure(c, 400, "invalid-request", ...)
漏写 .catch 就是一个畸形请求打出 500。

- http.ts 加 readJson(读 + 校验)和 parseBody(再加上 400)。parseBody 不给
  message 时回 zod 的第一条 issue —— 后台表单原来就是这么写的,fallback 文案
  「Invalid payload」/「参数错误」只在 issues 为空时才用得上,实际走不到
- 51 处换成 parseBody;另 3 处失败时带别的错误码或和路径参数一起判,换成 readJson
- 错误码、状态码、文案、判断顺序都不变

实跑核过:非 JSON 请求体回原来的固定文案,公告标题为空回 zod issue。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
xuyueandClaude Opus 5.5 committed 2026-09-27 15:04:19 +08:00
1 parent c43da01ff2
commit f2ca34fd4b
21 files changed
+234 -432

No files matched your search

+40
View File
@@ -1,4 +1,5 @@
import type { Context } from "hono"
import type { z } from "zod"
export function success<T>(c: Context, data: T, status = 200) {
return c.json({ data }, status as 200)
@@ -12,3 +13,42 @@ export function failure(
) {
return c.json({ error: { code, message } }, status)
}
/**
* 读 JSON 请求体并按契约校验。body 不是合法 JSON 时按 `null` 交给 schema,
* 由 schema 统一判失败 —— 原来每个 handler 都手写一遍 `c.req.json().catch(() => null)`,
* 漏写 `.catch` 就是一个畸形请求打出 500。
*/
export async function readJson<S extends z.ZodType>(c: Context, schema: S) {
return schema.safeParse(await c.req.json().catch(() => null))
}
/**
* `readJson` + 校验失败时的 400。绝大多数入参端点就是这个形状:
*
* const parsed = await parseBody(c, schema, "标签名不能为空")
* if (!parsed.success) return parsed.response
*
* 不给 `message` 就回 zod 的第一条 issue(后台表单要告诉老师具体哪一栏不对)。
* 失败时要带别的错误码、或者和路径参数一起判的,用 `readJson` 自己写。
*/
export async function parseBody<S extends z.ZodType>(
c: Context,
schema: S,
message?: string,
): Promise<
{ success: true; data: z.output<S> } | { success: false; response: Response }
> {
const parsed = await readJson(c, schema)
if (parsed.success) return { success: true, data: parsed.data }
return {
success: false,
response: failure(
c,
400,
"invalid-request",
// issues 不会是空的,?? 只是给类型一个交代
message ?? parsed.error.issues[0]?.message ?? "参数错误",
),
}
}