diff --git a/用户可见错误文案规范.html b/用户可见错误文案规范.html deleted file mode 100644 index f1c04c1..0000000 --- a/用户可见错误文案规范.html +++ /dev/null @@ -1,589 +0,0 @@ - - - - - - 用户可见错误文案规范 · cn-rdms - - - - -
-
-

用户可见错误文案规范

-

来源:技术负债 TD-012 · 落地日期 2026-06-03 · 文档 2026-06-04

-

- 适用范围:整仓所有"状态机动作 / 状态校验失败"的业务异常,凡 - message - 会被前端直接展示者 -

-

- 给前端 - toast - 的 - message - 只放用户能看懂的中文;动作 / 状态的内部 code、堆栈等技术细节不进 - message - ,由访问日志承载。本规范是必须遵守的跨模块约定,新功能照做。 -

-
- -

1 · 核心理念

-

message 面向用户、诊断面向开发,两者分离。

-

- 前端往往直接把后端业务异常的 - message - 弹给最终用户。如果 - message - 里夹着 - complete - / - status - / - action - 这类内部术语,用户看不懂,会误以为系统异常或数据没保存。 -

-
-
反例(TD-012 的原始案例)
- 用户点"完成任务",第一次请求已把任务置为已完成;前端重复发了第二次 - complete - 动作,后端返回 - "当前任务状态不支持动作【complete】" - 。用户合理的预期是看到 - "任务已完成,请勿重复提交" - 这类人话。 -
-

- 因此约定: - - 用户看友好中文( - message - ),开发排查看访问日志( - infra_api_access_log - 里有原始 code、入参、堆栈)。 - - 两条信息流互不污染。 -

- -

2 · 技术实现

-

- 整套方案 - 零新表、framework 零改动 - ,纯在 - rdms-project - 域内:一个解析器组件 + 错误码文案模板改造 + service 接入。 -

- -

- 2.1 文案解析器 - StatusActionTextResolver -

-

- 位置: - rdms-project-boot · service/status/StatusActionTextResolver.java - ( - @Component - )。把动作 / 状态的 code 翻成中文展示名,供错误文案使用。 -

- - - - - - - - - - - - - - - - - - - - -
方法作用查不到 / 空入参
actionName(objectType, actionCode)动作中文名 - 回退原 - actionCode - ,不抛错 -
statusName(objectType, statusCode)状态中文名 - 回退原 - statusCode - ,不抛错 -
-
-
权威源:DB 状态机表,不在代码里硬编码映射
- 动作名取自 - rdms_object_status_transition.action_name - ,状态名取自 - rdms_object_status_model.status_name - 。运维在状态机表里配新动作 / 新状态,文案自动生效, - 不用改代码发版 - 。 -
- -

2.2 错误码文案用「{}」占位中文名

-

错误码定义时,文案就留中文名占位,由 service 在抛错前用 resolver 填入。例如:

-
// 个人事项 —— 正面样板
-ErrorCode PERSONAL_ITEM_STATUS_ACTION_NOT_ALLOWED =
-    new ErrorCode(1_008_008_004, "当前个人事项为「{}」状态,不支持「{}」操作");
-

- 抛出前: - - exception(PERSONAL_ITEM_STATUS_ACTION_NOT_ALLOWED, resolver.statusName(...), resolver.actionName(...)) - - —— 占位填的是中文名,不是裸 code。 -

- -

2.3 已接入面(7 个 service)

-

状态机校验失败抛错时,先经 resolver 翻译再返回的 service:

- - -

3 · 关键设计决策

-
    -
  1. - 不硬编码映射,跟 DB 状态机走。 - 中文名是状态机表里运维可配的数据,不复刻成 Java 常量 / Enum;加新动作、新状态不需要改代码(呼应仓库"字典 / - 状态值不复刻成 Java 常量"的纪律)。 -
  2. -
  3. - 解析器只翻译、绝不抛错。 - 空入参或查不到一律回退原 code。它是文案美化层,不能反过来变成新的故障点——翻译失败也要让原始业务异常正常返回。 -
  4. -
  5. - 轻量、可回滚。 - 纯加一个 Component + 改错误码文案模板 + service 接入,不新表、不动 framework、复用现有错误码体系,因此 - 无演示库补丁、前端零改动 - 。 -
  6. -
- -

4 · 新功能落地清单

-
-
凡新增"状态机动作 / 状态校验"且 message 会被前端展示,照此四步
-
-
    -
  1. - service 注入 - StatusActionTextResolver - 。 -
  2. -
  3. - 错误码文案写成「{}」占位中文名(参考 - PERSONAL_ITEM_STATUS_ACTION_NOT_ALLOWED - ), - 不要把 code 直接嵌进文案 - 。 -
  4. -
  5. - 抛错前用 - actionName / statusName - 把 code 翻成中文名再填占位。 -
  6. -
  7. - 新对象类型在 - rdms_object_status_model - / - rdms_object_status_transition - 配好 - status_name - / - action_name - ,resolver 即自动生效。 -
  8. -
- -

5 · 信息泄漏类红线

-

- 除"状态机动作 / 状态翻中文"外,凡 - message - 会被前端直接展示, - 以下技术 token 一律不得出现在 message 里 - ,只能进日志( - log.warn - / - infra_api_access_log - ): -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
禁止外泄反例正确做法
数据库表名 / 列名 - "未在 - system_role - 找到" - "…未配置,请联系管理员"
权限码 / 内部标记 - "操作权限【 - project:project:update - 】"、"【 - member - 】" - "您没有此项操作权限,请联系管理员"
动作 / 状态 code - "不支持动作【 - complete - 】" - resolver 翻中文名(见 §2)
类名 / 字段名 / 堆栈 - " - NullPointerException at ... - " - 友好提示,异常进日志
-
-
2026-06-04 · B 类存量整改已落地
- -
-
-
2026-06-04 · 加班申请 service 层单测已补
- 新增 - OvertimeApplicationServiceImplTest - (2 用例, - mvn test - 通过):验证状态机「动作不允许 / 缺原因」抛错时, - message - 填的是 - StatusActionTextResolver - 翻出的中文名、不外泄英文动作 / 状态 code。属 Mockito 单测(mock resolver),覆盖的是 service 层「填中文名而非裸 - code」这条契约;resolver 自身的 DB 翻译由 - StatusActionTextResolverTest - 覆盖。真实 DB 状态机表是否配齐 - status_name - / - action_name - 的端到端校验仍依赖运行时,不在单测范围。 -
- -

6 · 关联文档

- - - -
- -