一、网关错误Schema
```ts
type ErrorPayload = { code: string; message: string; traceId: string; hint?: string }
const statusByCode: Record = { bad_request: 400, unauthorized: 401, forbidden: 403, not_found: 404, rate_limited: 429, server_error: 500 }
```
二、网关封装
```ts
type Req = { headers: Record }
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 setHeaders(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 sendError(req: Req, res: Res, code: keyof typeof statusByCode, msg: string, hint?: string) { const id = traceId(req); setHeaders(res, id); const p: ErrorPayload = { code, message: msg, traceId: id, hint }; res.status(statusByCode[code]).end(JSON.stringify(p)) }
```
三、SDK解析与建议
```ts
type SdkError = { code: string; message: string; traceId: string; retry?: boolean }
function parseError(resp: Response): Promise { return resp.json().then((p: any) => ({ code: String(p.code || 'server_error'), message: String(p.message || 'error'), traceId: String(p.traceId || ''), retry: resp.status === 429 || resp.status >= 500 })) }
```
四、国际化与提示
```ts
const i18n: Record = { unauthorized: '未授权', forbidden: '禁止访问', not_found: '资源不存在', rate_limited: '请求过于频繁', server_error: '服务异常' }
function i18nMsg(code: string): string { return i18n[code] || '请求错误' }
```
五、指标采样
```ts
class Metrics { counts = new Map(); inc(k: string) { const n = (this.counts.get(k) || 0) + 1; this.counts.set(k, 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) }
```
六、验收清单
- 网关统一`code→HTTP`映射与错误Schema;传播`X-Trace-Id`与`nosniff`头。
- SDK解析错误并提供重试建议;国际化提示与统一消息。
- 指标采样记录错误码分布;CI检测错误Schema一致性与覆盖率。
发表评论 取消回复