Files
Genarrative/docs/technical/【技术方案】AGC错误报告与诊断上传-2026-08-31.md
T
k88936 9c8c105585 同步错误报告分页与存储决策文档
记录 UUID OSS key、元数据索引和分页响应约定

从 review.txt 移除已完成的 2、4、5、6、9 项
2026-09-01 16:29:02 +08:00

5.1 KiB
Raw Blame History

AGC 错误报告与诊断上传

范围

AI Game Creator Shell 采用 IDEA 风格的当前进程错误报告:错误事件在内存池中按 fingerprint 合并;应用级诊断日志持续写入 Tauri AppData 的滚动文件;用户打开“报告问题”面板并确认后,一次提交当前进程选中的错误事件和脱敏应用日志。项目目录 .agent/logs/*、源码、prompt、配置、项目产物和截图不进入报告包。

客户端

  • 捕获 React render error、window.onerrorunhandledrejection 以及显式标记的 Tauri/API/Agent 错误。
  • 事件字段包括 eventId、fingerprint、source、message、stack、时间和次数;重复事件合并。不再携带 severity、errorCode、page、action、requestId 等无法稳定关联的字段。
  • 指纹计算可使用调用方的 page/action 及脱敏后的首个调用点作为进程内区分输入,但这些上下文不会作为事件字段上传;消息与 stack 在入池前统一脱敏,WebCrypto 失败时降级为稳定可读指纹,采集本身不得产生新的未处理拒绝。
  • 客户端 API 自动采集只覆盖网络错误、408 和 5xx;预期的 4xx 登录/鉴权失败不进入错误报告池。
  • Rust 侧通过 app_log! 将普通文本日志同时输出到 stderr 和 AppData diagnostics/application.log,超出 256 KiB 滚动到 application.previous.logWebView 的 console 输出通过 append_application_log 镜像到同一 raw log,并在客户端桥接处再次脱敏;read_diagnostic_logs 只读取应用级日志。
  • 报告面板允许填写最多 2,000 字中文描述并取消日志附件;本版本不支持截图或任意文件附件。
  • 上传失败只在当前进程显示失败并允许用户再次提交,不跨重启恢复事件池,不后台自动重试。

HTTP 与存储

  • 登录态客户端使用 POST /api/error-reports,请求 DTO 位于 shared-contracts::error_reports
  • api-server 对请求体设置 24 MiB 上限,并校验 schemaVersion、submissionId、事件/日志数量和 20 MiB 压缩包上限;事件字段、用户说明和日志名/内容均做长度限制与基础脱敏,归档使用 events.jsonl(每行一个事件)。结构化事件只保存在当前进程内,用户提交时才生成 events.jsonl,不在磁盘单独持久化。submissionId 提供重放幂等。
  • 归档构建会短暂使用一个受 20 MiB 上限约束的内存 Vec<u8>,随后立即写入私有本地归档;不把 ZIP 长期留在内存。这样既控制峰值,又支持进程重启后后台查看/下载和 OSS 上传失败后的本地取证。
  • 本地 error-reports/index.json 保存元数据索引;创建时用索引完成 submission 幂等查找,管理员列表从索引读取并分页。索引缺失时会从现有元数据文件一次性重建。
  • 归档对象使用固定私有 OSS keyagc/error-reports/v1/{batchId}.zip;key 只由报告 UUID 决定,不包含时间戳。api-server 先写 uploading 元数据,上传成功后记录 ossObjectKey、SHA-256、大小和 ready 状态;相同 submission 重放对已 ready 报告直接返回,不重复上传。完整事件、说明和日志不进入元数据记录。
  • agc 是服务端专用私有前缀;公共直传票据、通用 object-key 规范化和 legacy 公开路径均拒绝该前缀。归档内同名日志会自动加数字后缀,读取本机诊断日志时拒绝符号链接/非普通文件。
  • 后台接口:GET/PATCH /admin/api/error-reports/{batchId}GET /admin/api/error-reports 和受保护的 /download。列表支持 limit/offset 分页并返回 totalhasMore
  • 这些是 api-server 内部登录/管理员路由,不属于 /api/external/v1,不纳入 External OpenAPI;管理员详情对不存在返回 404,对归档/元数据损坏返回 500。
  • admin viewer 仅接受 error-reports Tab 权限,支持列表筛选、分页、详情、状态 new/in-progress/resolved、处理备注和受控下载;不存在的更新目标返回 404,存储损坏返回 500。列表行支持键盘 Enter/Space 打开详情,详情事件预览最多显示 20 条,完整内容通过诊断包下载获取。
  • 当前兼容实现仍在 api-server 配置目录旁保留元数据与本地归档副本,便于无 OSS 配置的开发环境运行;生产配置启用 OSS 后以 OSS 对象为完整内容来源。SpacetimeDB error_report 私有表接入及 30 天 OSS/元数据清理 worker 为后续门禁,HTTP DTO 与管理员权限保持不变。

验收

npm run typecheck --workspace @genarrative/ai-game-creator-shell
npx tsc -p apps/admin-web/tsconfig.json --noEmit
npx vitest run apps/ai-game-creator-shell/tests/errorReporting.test.ts apps/ai-game-creator-shell/tests/clientRuntimeErrorBoundary.test.ts apps/admin-web/src/app/adminRoutes.test.ts
cargo test -p api-server --bin api-server error_reports -- --nocapture
cargo fmt -p api-server -p shared-contracts -- --check
npm run check:encoding
git diff --check

Rust 全量检查还受现有 platform-llm ProviderReasoningEffort::Max 编译错误阻塞;本变更未修改该历史问题。