一、错误Schema与映射type ErrorPayload = { code: string; message: string; traceId: string; hint?: string }
const statusByCode: Record<string, number> = {
'bad_request': 400,
'unauthorized': 401,
'forbidden': 403,
'not_found': 404,
'rate_limited': 429,
'server_error': 500
}
function toStatus(code: string): number { return statusByCode[code] || 500 }
二、Trace-ID与头字段type Req = { headers: Record<string, string | undefined> }
type Res = { setHeader: (k: string, v: string) => void; status: (n: number) => Res; end: (b?: string) => void }
function traceId(req: Req): string { return req.headers['x-trace-id'] || Math.random().toString(36).slice(2) }
function setCommonHeaders(res: Res, id: string) {
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res.setHeader('X-Content-Type-Options', 'nosniff')
res.setHeader('X-Trace-Id', id)
}
三、错误封装与输出function makeError(code: string, message: string, traceId: string, hint?: string): ErrorPayload { return { code, message, traceId, hint } }
function sendError(req: Req, res: Res, code: string, message: string, hint?: string) {
const id = traceId(req)
setCommonHeaders(res, id)
const payload = makeError(code, message, id, hint)
res.status(toStatus(code)).end(JSON.stringify(payload))
}
四、指标与采样class Metrics {
counts = new Map<string, number>()
inc(key: string) { const n = (this.counts.get(key) || 0) + 1; this.counts.set(key, n) }
}
function sample(p: number): boolean { return Math.random() < p }
function record(metrics: Metrics, code: string, p = 0.1) { if (sample(p)) metrics.inc(code) }
五、整合中间件function guardExample(req: Req, res: Res, metrics: Metrics) {
const ok = (req.headers['authorization'] || '').startsWith('Bearer ')
if (!ok) { record(metrics, 'unauthorized'); return sendError(req, res, 'unauthorized', '缺少或无效授权', '检查令牌') }
}
六、验收清单错误码与状态码映射统一;错误Schema包含`code/message/traceId/hint`。`X-Trace-Id`传播一致;头字段包含`Content-Type`与`nosniff`;重试建议通过`hint`提供。指标采样与统计可用;日志与错误输出遵循统一格式并可脱敏。

发表评论 取消回复