3、错误码设计总纲:错误码的组成结构、分类原则、版本管理、国际化考虑

错误码是BFF层与前端、下游微服务之间进行故障沟通的“通用语言”。一套设计不良的错误码会导致前端无法准确展示提示、监控系统无法聚合告警、排查人员需要反复查阅文档。本章从组成结构、分类原则、版本管理和国际化四个维度,建立BFF错误码设计的顶层规范。

3.1 错误码的组成结构

BFF错误码采用三段式结构:服务域(2位) + 错误类别(2位) + 具体错误(4位),共8位字符,全部使用大写字母和数字组合。

段位 位数 示例 说明
服务域 2位 OR 标识错误来源的BFF模块或聚合服务,如Order、User、Payment
错误类别 2位 04 标识错误大类:参数校验、鉴权、业务逻辑、系统异常等
具体错误 4位 1023 标识具体错误场景,按模块递增分配,不重复使用
完整示例:OR041023 → 订单服务(OR) → 业务逻辑错误(04) → 库存扣减失败,商品ID不存在(1023)

三段式结构在日志和监控系统中可以快速做前缀聚合:按前4位聚合可统计某模块某类错误的频率;按全码匹配可定位到具体故障点。

设计原则:错误码一旦发布进入生产环境,其含义不可变更。废弃的错误码应标记为“已弃用”并保留在注册表中,避免未来重复分配导致歧义。

3.2 错误码分类原则

错误类别(第3-4位)采用数字区间分类法,每个区间对应一类错误语义,便于前端做统一的UI提示策略。

类别码 分类名称 典型场景 前端处理策略
01 参数校验错误 必填字段缺失、格式不合法、枚举值越界 高亮对应输入框,展示具体字段提示
02 鉴权与授权错误 Token过期、无权限访问、签名校验失败 跳转登录页或弹窗提示重新授权
03 资源不存在 订单不存在、用户不存在、商品已下架 展示404风格页面或toast提示
04 业务逻辑错误 库存不足、重复提交、状态冲突 弹窗或页面内提示具体业务原因
05 依赖服务异常 下游超时、熔断、返回非预期数据 展示“服务繁忙,请稍后重试”
06 系统内部错误 空指针、数据库连接失败、配置加载异常 统一兜底页面,不暴露具体堆栈
99 未知/预留 未匹配到任何已知错误码 记录告警日志,展示通用错误提示
避坑提醒:不要将下游微服务的原始错误码直接透传给前端。BFF应做错误码映射,将下游的多种错误收敛到BFF定义的类别区间内,避免前端感知后端服务拆分细节。
错误码三段式结构解析 OR 服务域(2位) 04 错误类别(2位) 1023 具体错误(4位) 完整错误码:OR041023 服务域含义 OR = Order 订单聚合服务 类别含义 04 = 业务逻辑错误 库存/状态冲突 具体含义 1023 = 库存扣减失败 商品ID不存在

3.3 错误码版本管理

错误码是BFF接口契约的一部分,需要像API版本一样进行管理。推荐采用注册表 + 变更日志的双重管理机制。

3.3.1 错误码注册表

在BFF项目源码中维护一个error-code-registry.yaml文件,作为唯一事实来源。每次新增、弃用或修改错误码都必须更新该文件并通过Code Review。

# error-code-registry.yaml 示例片段
version: "1.0"
last_updated: "2025-03-15"
entries:
  - code: "OR041023"
    status: active
    category: "业务逻辑错误"
    message_en: "Inventory deduction failed: product ID not found"
    message_zh: "库存扣减失败:商品ID不存在"
    introduced_in: "v2.1.0"
    deprecated_in: null
    removed_in: null

  - code: "OR040512"
    status: deprecated
    category: "业务逻辑错误"
    message_en: "Order status conflict"
    message_zh: "订单状态冲突"
    introduced_in: "v1.3.0"
    deprecated_in: "v2.0.0"
    removed_in: "v2.3.0"
    deprecation_reason: "合并到OR040513,提供更精确的状态描述"

3.3.2 版本变更规则

操作 规则 兼容性影响
新增 分配未使用过的具体错误码(4位),不可复用已弃用码 向前兼容,前端需更新提示文案
弃用 标记为deprecated,保留在注册表中,至少保留2个大版本 前端可继续使用,但应计划迁移
移除 仅允许在deprecated状态持续2个大版本后执行 破坏性变更,需同步更新前端和客户端
语义变更 禁止修改已有错误码的语义;应新增码并弃用旧码 避免监控和历史数据出现歧义
自动化建议:在CI流水线中加入错误码注册表校验脚本,检查是否存在重复码、已移除码被引用、或新增码未填写中英文消息。确保错误码规范在代码合入前即被强制执行。

3.4 国际化考虑

BFF错误码本身是纯字母数字,不包含任何自然语言,因此天然具备国际化能力。前端根据错误码查询对应的本地化消息模板即可。

3.4.1 消息模板分层

错误码对应的用户提示消息采用三层模板结构,兼顾通用性和场景定制:

  • L1 通用模板:按错误类别定义,如类别04统一为“业务处理失败,请稍后重试”。当前端未找到具体错误码的L2模板时使用。
  • L2 具体模板:按完整错误码定义,如OR041023对应“库存扣减失败,该商品可能已下架”。包含业务上下文。
  • L3 字段级模板:针对参数校验错误(类别01),额外返回具体字段名和校验规则,前端可精确绑定到表单控件。

3.4.2 多语言资源文件

在BFF项目中按语言维护独立的属性文件或JSON,与错误码注册表保持同步。

// messages/zh-CN.json
{
  "OR041023": "库存扣减失败:商品ID不存在,请刷新后重试",
  "OR040513": "订单状态冲突:当前订单不允许取消操作",
  "default_04": "业务处理异常,请稍后重试"
}

// messages/en-US.json
{
  "OR041023": "Inventory deduction failed: product ID not found, please refresh",
  "OR040513": "Order status conflict: current order cannot be cancelled",
  "default_04": "Business processing error, please retry later"
}
错误码国际化消息查找流程 错误码 OR041023 L2 具体模板是否存在? 是 返回 L2 具体消息模板 否 降级 L1 类别 通用模板 前端渲染本地化提示

3.4.3 响应体中的国际化字段

BFF返回给前端的错误响应中,除了错误码外,应携带message(当前语言环境下的提示)和可选的localized_fields(字段级错误详情)。

{
  "code": "OR041023",
  "message": "库存扣减失败:商品ID不存在,请刷新后重试",
  "localized_fields": null,
  "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "timestamp": 1710518400000
}
最佳实践:BFF层根据请求头中的 Accept-Language 或自定义 X-Locale 头确定语言,在响应中直接填充对应语言的 message 字段。前端优先使用该字段展示,无需再发起一次翻译查询。