防御式解析与错误信封
构建稳健的请求处理流程:进行防御式解析,将所有失败映射为紧凑的 JSON 错误信封,并避免泄露内部实现细节。
防御式解析与错误信封 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 2 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 2 节课。
简介
目标:进行防御式解析,并始终返回可预测的 JSON 错误信封。我们会将验证放在边界附近,统一失败结果,并让日志内容丰富而响应保持简洁。
- 对所有不受信任的输入使用 safeParse
- 一致的{ 错误, 代码, 详情? }
- 严格区分 4xx 与 5xx
信封映射器
定义一个小型、可复用的 ErrorEnvelope。将 unknown 错误映射为它,同时不要暴露堆栈跟踪。
export type ErrorEnvelope = { error: string; code?: string; details?: unknown }
export function toEnvelope(u: unknown): ErrorEnvelope {
if (u instanceof Error) return { error: u.message }
if (typeof u === "string") return { error: u }
try { return { error: JSON.stringify(u) } } catch { return { error: "Unknown error" } }
}验证辅助函数
将模式封装在一个validate辅助函数中,返回判别式结果。这样处理器可以保持简短且一致。
import { z, type ZodTypeAny } from "zod"
export function validate<T extends ZodTypeAny>(schema: T, value: unknown) {
const r = schema.safeParse(value)
if (!r.success) {
return { ok: false as const, issues: r.error.format() }
}
return { ok: true as const, data: r.data as z.infer<T> }
}防御式处理器
尽早验证;返回带有问题详情的 400。意外失败会传播到错误中间件,由它以信封形式返回 500。
import type { Request, Response, NextFunction } from "express"
import { z } from "zod"
import { validate } from "./validate"
import { toEnvelope, type ErrorEnvelope } from "./envelope"
const bodySchema = z.object({ email: z.string().email(), newsletter: z.boolean().default(false) })
export function subscribe(req: Request, res: Response<{ ok: true } | ErrorEnvelope>, next: NextFunction) {
const r = validate(bodySchema, req.body)
if (!r.ok) return res.status(400).json({ error: "Invalid body", details: r.issues })
try {
// pretend to persist
return res.status(201).json({ ok: true })
} catch (e) {
return next(e)
}
}
export function errorMiddleware(err: unknown, _req: Request, res: Response<ErrorEnvelope>, _next: NextFunction) {
const env = toEnvelope(err)
res.status(500).json(env)
}常见信封
为常见结果提供小型辅助函数:使用稳定的 code 字符串返回404/401,让客户端能够可靠地进行分支处理。
export function notFound(resource: string): { status: 404; body: { error: string; code: string } } {
return { status: 404, body: { error: `${resource} not found`, code: "NOT_FOUND" } }
}
export function unauthorized(): { status: 401; body: { error: string; code: string } } {
return { status: 401, body: { error: "unauthorized", code: "UNAUTHORIZED" } }
}日志与响应
平衡日志与响应:在服务器端记录完整错误(堆栈、请求 ID、用户 ID),但只向客户端返回最小化信封。请考虑速率限制以及对 PII 的脱敏。
信封实践检查
快速检查:验证错误应如何返回?
回顾
回顾:使用 safeParse 验证输入,将失败结果映射为紧凑的信封,并将丰富的日志与简洁的客户端响应分离。
常见问题解答
「防御式解析与错误信封」课时是免费的吗?
是的 — 「防御式解析与错误信封」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 2 节课。
「防御式解析与错误信封」这节课中我会学到什么?
构建稳健的请求处理流程:进行防御式解析,将所有失败映射为紧凑的 JSON 错误信封,并避免泄露内部实现细节。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 TypeScript Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 2 节。
「防御式解析与错误信封」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 TypeScript Academy 课中编写并运行代码吗?
能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- zod/valibot 模式与类型推断
- 防御式解析与错误信封