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定义的类别区间内,避免前端感知后端服务拆分细节。
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"
}
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 字段。前端优先使用该字段展示,无需再发起一次翻译查询。