文档:本机IO失败去掉detail载荷

- 命令错误结构化 ADR:本机凭据/运行时会话 IO 失败不再把原始错误文本放进载荷,原始 error 只写本地日志
- 认证失败 JS 侧载体 ADR 与决策记录同步去掉 detail 口径,并追加 2026-10-02 的变体改无字段决定
This commit is contained in:
2026-10-02 11:51:28 +08:00
parent b54b3794f6
commit 8edbab9f3e
3 changed files with 7 additions and 5 deletions
@@ -46,8 +46,9 @@ DirectProject 已经解决过同一类问题([`【ADR】DirectProject命令接
Java 的嵌套 `switch`,仍不碰文案)。顶层与 `reason` 的 `default` 都用 `expectNever`,漏接变体或漏接
`reason` 都是**编译错误**。**不假设所有变体都有同一个字段**,也不做任何文案匹配。
- Rust **不预拼用户可见文案**:载荷只装原始事实(类型化的 `reason`、服务端 400 的原文 `serverMessage`、
HTTP 状态码、本机 IO 的 `detail`),服务端没给原文就是 `None`;前缀与句式由前端调用方在自己的 catch
分支按当前操作拼接。
HTTP 状态码),服务端没给原文就是 `None`;前缀与句式由前端调用方在自己的 catch 分支按当前操作拼接。
本机凭据 / 运行时会话的 IO 失败不再把原始错误文本放进载荷(它曾把 AppData 路径带进登录页与上报包),
原始 `error` 只写本地日志;对应变体是无字段变体,前端给固定文案。
- `#[tauri::command]` 的 `Err` 直接携带该枚举(Tauri 2 的 `InvokeError(pub serde_json::Value)` 支持结构化错误)。
这是 DirectProject 已有的做法(`enqueue_direct_codex_turn -> Result<(), DirectTurnEnqueueFailure>`),不是新约定。
- 变体按**可判定的事实**命名。服务端 400 只提供 `status + message`(`AppError.code` 仍是通用
@@ -109,10 +109,10 @@ catch (error) {
细分 `reason` 时,再 `switch (payload.reason)` 在类型化枚举上分流。无字段的 `case` 直接用本 catch 的
固定文案。不写跨变体的通用读取,也不让 Rust 预拼上下文。前缀取自当前 catch 的操作语义(登录、发码、
启动检查各自可以不同),等价于 Java 的 `catch (PasswordLoginRejected e)`。系统变体先按载荷里的原始
事实(`reason` / `status` / `detail` / `serverMessage`)给一行可见反馈,再原样抛出;变体名必须逐个
事实(`reason` / `status` / `serverMessage`)给一行可见反馈,再原样抛出;变体名必须逐个
列出,`default` 的 `expectNever` 才成立。
- 业务 / 会话变体:Rust 只给可判定事实(无字段变体连字段都没有;带载荷变体给类型化 `reason` /
`serverMessage` / `status` / `detail`),调用方在自己的 catch 里补上本次操作的上下文前缀(例如
`serverMessage` / `status`),调用方在自己的 catch 里补上本次操作的上下文前缀(例如
「服务器地址非法: 远程地址必须使用 https」、「登录失败: 密码长度需要在 6 到 128 位之间」)。
- 系统变体:调用方处理不了,先给一行可见反馈(载荷原始事实,不建兜底文案层),再**原样 `throw`**。
`onSubmit` / `onClick` 这类 `void` 掉的 handler 抛出的拒绝最终以 `unhandledrejection` 结算,由全局