[W-01][medium] 后台错误处理:不处理 401、每个错误弹两次、网络错误显示英文、表单错误只闪 toast、页面加载失败一片空白 #51

Closed
opened 2026-09-30 13:57:04 +08:00 by nixevol · 1 comment
Owner

编号:W-01 严重级:medium 工作线:后台网页(web/) 来源:审查 A-08、A-21
依赖:无 被依赖:无

结论与统一方案

采用审查 A-08、A-21 的方案:

  1. 错误只弹一次(run() 不再重复弹 ApiError)。
  2. requestAdmin 遇到 401(排除 /api/admin/login 与 /api/admin/password)时清空登录状态并跳转 /login?redirect=当前路径,提示一次"登录已过期";用 main.ts 注册回调,避免循环引用。
  3. 网络错误显示"无法连接服务器";429 提示稍后再试。
  4. 表单用 n-form 的 rules 按 PRD 限制就地校验;服务端返回的错误放进弹窗内的 n-alert。
  5. 页面加载失败时显示 n-result 或 n-alert,并提供"重试"。
  6. 开通端时名称改为可选(PRD F01);管理员密码长度统一按字符数计,并修正帮助文字(后端 login.go 同步按字符数)。
  7. 清除对话密码与生成新安全码加确认。

改动文件

web/src/api/http.ts、admin.ts、main.ts 或 stores/auth.ts、各 views/*.vue;internal/admin/login.go(密码长度按字符数,一处)。

与其他问题的交互 / 冲突说明

  • 与 H-06 的改密 401 语义互相排除。
  • RegistrationView 的开关逻辑归 U-01,本条只改其错误提示与确认。

验收与测试

  • 模拟 fetch 返回 401,断言跳到登录页且只提示一次。
  • 组件测试断言表单就地显示错误;页面加载失败显示重试。

问题明细(各区审查原文,证据含文件与行号)

以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。解决方案以本 issue 上方的"结论与统一方案"为准;原文里的方案与之不一致时,按上方执行。

[A-08] 前端不处理 401,所有错误提示都弹两次

  • 严重级:medium
  • 分类:协议一致性 / 界面
  • 现象与影响:
    • requestAdmin 弹一次错误,run() 捕获后又弹一次。
    • 会话 12 小时过期,或在别处改了管理员密码导致本会话作废后,每个页面都弹两次"未登录",但不会跳回登录页。点"退出"也会先报错。
    • 网络错误直接显示英文 "Failed to fetch"。
  • 证据:
    • web/src/api/http.ts:80-83 在非 silent 时弹错误并抛出。
    • web/src/api/admin.ts:32-43 的 run() 再弹一次。
    • router/index.ts:30-45 和 stores/auth.ts:11-20 只在首次导航时检查登录状态。
  • 文档依据:TASKS W1"请求封装(CSRF 头、错误提示)";用户界面规则"真实工作流可用"。
  • 为何不是故意设计:DEVIATIONS 没有相关条目。
  • 解决方案:
    1. 错误只弹一次,例如 run() 不再弹 ApiError。
    2. requestAdmin 遇到 401 时,除 /api/admin/login 和 /api/admin/password 外,都清空登录状态并跳转 /login?redirect=当前路径,提示一次"登录已过期"。用 main.ts 注册回调,避免循环引用。
    3. 网络错误改成中文"无法连接服务器";429 提示稍后再试。
  • 改动文件:web/src/api/http.ts、admin.ts、main.ts 或 stores/auth.ts。
  • 交互/冲突风险:改密码时旧密码错误返回的是 401(契约如此),必须排除在自动登出之外(另见 A-16)。
  • 需补测试:模拟 fetch 返回 401,断言跳到登录页且只弹一次提示。
  • 置信度:代码阅读确定

[A-21] 表单错误只用 toast、页面加载失败时一片空白、校验和帮助文字与规则不一致

  • 严重级:low
  • 分类:界面
  • 现象与影响:
    • 所有表单都设了 :show-feedback="false",后端校验错误只在 toast 里一闪而过。
    • 概览、注册设置、系统页加载失败后是空白,没有错误提示和重试。
    • 开通时名称必填(EndpointsView.vue:194-197),但 PRD 规定名称可选。
    • 对话密码弹窗没有 4–64 字符的提示,也没有 loading;留空保存会直接清除密码,没有确认。
    • 系统页帮助文字说管理员密码"不能以 nst_ 开头",后端并不检查(SettingsView.vue:67-69)。长度的计法前端按 .length,后端按字节,端密码按字符数,三处不一致。
    • 注册设置页:生成新安全码没有确认;开关后输入框里未保存的草稿仍显示,容易误以为已生效。
  • 证据:EndpointsView.vue:410,441,465;GroupsView.vue:269,302;RegistrationView.vue:68;SettingsView.vue:35,62;OverviewView.vue:12-18;login.go:123-127。
  • 文档依据:用户界面规则"错误、警告、关键状态直接展示";PRD F01(约 127 行)名称可选;D31。
  • 为何不是故意设计:DEVIATIONS 没有相关条目。
  • 解决方案:
    1. 表单用 n-form 的 rules 按 PRD 限制做校验,就地显示错误;服务端返回的错误放进弹窗内的 n-alert。
    2. 页面加载失败时显示 n-result 或 n-alert,并提供"重试"。
    3. 去掉名称必填。
    4. 管理员密码长度统一按字符数计,并修正帮助文字。
    5. 清除对话密码和生成新安全码都加确认。
  • 改动文件:各 views/*.vue、internal/admin/login.go。
  • 交互/冲突风险:与 A-08 的统一错误处理配合。
  • 需补测试:组件测试断言就地显示错误。
  • 置信度:代码阅读确定

复审基线:main 4059a15(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。

**编号**:W-01 **严重级**:medium **工作线**:后台网页(web/) **来源**:审查 A-08、A-21 **依赖**:无 **被依赖**:无 ### 结论与统一方案 采用审查 A-08、A-21 的方案: 1. 错误只弹一次(`run()` 不再重复弹 `ApiError`)。 2. `requestAdmin` 遇到 401(排除 `/api/admin/login` 与 `/api/admin/password`)时清空登录状态并跳转 `/login?redirect=当前路径`,提示一次"登录已过期";用 `main.ts` 注册回调,避免循环引用。 3. 网络错误显示"无法连接服务器";429 提示稍后再试。 4. 表单用 `n-form` 的 rules 按 PRD 限制就地校验;服务端返回的错误放进弹窗内的 `n-alert`。 5. 页面加载失败时显示 `n-result` 或 `n-alert`,并提供"重试"。 6. 开通端时名称改为可选(PRD F01);管理员密码长度统一按字符数计,并修正帮助文字(后端 `login.go` 同步按字符数)。 7. 清除对话密码与生成新安全码加确认。 ### 改动文件 `web/src/api/http.ts`、`admin.ts`、`main.ts` 或 `stores/auth.ts`、各 `views/*.vue`;`internal/admin/login.go`(密码长度按字符数,一处)。 ### 与其他问题的交互 / 冲突说明 - 与 H-06 的改密 401 语义互相排除。 - RegistrationView 的开关逻辑归 U-01,本条只改其错误提示与确认。 ### 验收与测试 - 模拟 fetch 返回 401,断言跳到登录页且只提示一次。 - 组件测试断言表单就地显示错误;页面加载失败显示重试。 --- ### 问题明细(各区审查原文,证据含文件与行号) > 以下是本次复审各区审查报告的原文段落。A、M、I、P、S 开头的是原始发现编号(A 管理后台与网页、M 消息核心、I 身份认证群在线、P 传输平台部署、S SDK)。**解决方案以本 issue 上方的"结论与统一方案"为准**;原文里的方案与之不一致时,按上方执行。 #### [A-08] 前端不处理 401,所有错误提示都弹两次 - 严重级:medium - 分类:协议一致性 / 界面 - 现象与影响: - `requestAdmin` 弹一次错误,`run()` 捕获后又弹一次。 - 会话 12 小时过期,或在别处改了管理员密码导致本会话作废后,每个页面都弹两次"未登录",但不会跳回登录页。点"退出"也会先报错。 - 网络错误直接显示英文 "Failed to fetch"。 - 证据: - `web/src/api/http.ts:80-83` 在非 `silent` 时弹错误并抛出。 - `web/src/api/admin.ts:32-43` 的 `run()` 再弹一次。 - `router/index.ts:30-45` 和 `stores/auth.ts:11-20` 只在首次导航时检查登录状态。 - 文档依据:TASKS W1"请求封装(CSRF 头、错误提示)";用户界面规则"真实工作流可用"。 - 为何不是故意设计:DEVIATIONS 没有相关条目。 - 解决方案: 1. 错误只弹一次,例如 `run()` 不再弹 `ApiError`。 2. `requestAdmin` 遇到 401 时,除 `/api/admin/login` 和 `/api/admin/password` 外,都清空登录状态并跳转 `/login?redirect=当前路径`,提示一次"登录已过期"。用 `main.ts` 注册回调,避免循环引用。 3. 网络错误改成中文"无法连接服务器";429 提示稍后再试。 - 改动文件:`web/src/api/http.ts`、`admin.ts`、`main.ts` 或 `stores/auth.ts`。 - 交互/冲突风险:改密码时旧密码错误返回的是 401(契约如此),必须排除在自动登出之外(另见 A-16)。 - 需补测试:模拟 fetch 返回 401,断言跳到登录页且只弹一次提示。 - 置信度:代码阅读确定 #### [A-21] 表单错误只用 toast、页面加载失败时一片空白、校验和帮助文字与规则不一致 - 严重级:low - 分类:界面 - 现象与影响: - 所有表单都设了 `:show-feedback="false"`,后端校验错误只在 toast 里一闪而过。 - 概览、注册设置、系统页加载失败后是空白,没有错误提示和重试。 - 开通时名称必填(`EndpointsView.vue:194-197`),但 PRD 规定名称可选。 - 对话密码弹窗没有 4–64 字符的提示,也没有 loading;留空保存会直接清除密码,没有确认。 - 系统页帮助文字说管理员密码"不能以 nst_ 开头",后端并不检查(`SettingsView.vue:67-69`)。长度的计法前端按 `.length`,后端按字节,端密码按字符数,三处不一致。 - 注册设置页:生成新安全码没有确认;开关后输入框里未保存的草稿仍显示,容易误以为已生效。 - 证据:`EndpointsView.vue:410,441,465`;`GroupsView.vue:269,302`;`RegistrationView.vue:68`;`SettingsView.vue:35,62`;`OverviewView.vue:12-18`;`login.go:123-127`。 - 文档依据:用户界面规则"错误、警告、关键状态直接展示";PRD F01(约 127 行)名称可选;D31。 - 为何不是故意设计:DEVIATIONS 没有相关条目。 - 解决方案: 1. 表单用 `n-form` 的 rules 按 PRD 限制做校验,就地显示错误;服务端返回的错误放进弹窗内的 `n-alert`。 2. 页面加载失败时显示 `n-result` 或 `n-alert`,并提供"重试"。 3. 去掉名称必填。 4. 管理员密码长度统一按字符数计,并修正帮助文字。 5. 清除对话密码和生成新安全码都加确认。 - 改动文件:各 `views/*.vue`、`internal/admin/login.go`。 - 交互/冲突风险:与 A-08 的统一错误处理配合。 - 需补测试:组件测试断言就地显示错误。 - 置信度:代码阅读确定 --- <sub>复审基线:main `4059a15`(2026-09-30)。编号说明、各工作线的合并顺序、共享文件归属见总览 #7。</sub>
nixevol added the P2-mediumlane/webreview-2026-09-30 labels 2026-09-30 13:57:04 +08:00
Author
Owner

已合入 origin/main 0c9b459。落地提交 ed788fb fix: 统一管理后台 401 与加载失败处理 (#51)。

已合入 origin/main `0c9b459`。落地提交 `ed788fb` fix: 统一管理后台 401 与加载失败处理 (#51)。
Sign in to join this conversation.