20260429_231526-fix: upload field mismatch, WebSocket StrictMode crash, project list refresh after upload

This commit is contained in:
2026-04-29 23:17:09 +08:00
parent 4ec917efe7
commit d7d1e3225f
12 changed files with 260 additions and 10 deletions

View File

@@ -5,6 +5,32 @@
---
## 2026-04-29-23-15-26 — 上传/WS/项目库三 Bug 联修
### A. 具体问题
1. 上传成功后控制台打印 `undefined`,前端显示 url 为 `undefined`
2. React StrictMode 下 Dashboard 页面切换时报 `InvalidStateError: WebSocket is closed before the connection is established`
3. 上传完成后项目库为空,不显示新上传的项目
### B. 产生原因
1. 后端 `media.py` 上传接口返回字段为 `{object_name, file_url, size, message}`,而前端 `api.ts``uploadMedia` 直接 `return response.data`,调用方解构 `const { url, id }``url``undefined`
2. React 18 StrictMode 在开发环境下会 double-mount/unmount`Dashboard.tsx``useEffect` cleanup 调用 `progressWS.disconnect()`,后者无条件执行 `this.ws.close()`;若此时 WebSocket 仍处于 `CONNECTING`(状态 0调用 `.close()` 会抛出 InvalidStateError
3. `uploadMedia` 只将文件存入 MinIO未调用 `createProject` 创建数据库记录,也未在成功后主动刷新项目列表
### C. 解决方案
1. `api.ts`: 解构 `file_url``object_name`,返回 `{ url: file_url, id: object_name }`
2. `websocket.ts`: `disconnect()` 中增加 `readyState === WebSocket.OPEN` 判断,仅对已连接套接字调用 `.close()`
3. `ProjectLibrary.tsx`: `uploadMedia` resolve 后调用 `getProjects()``setProjects()` 刷新列表
4. `Dashboard.tsx`: 增加 `mounted` refcleanup 时置 `false`,回调中检查 `mounted`,并延迟 500ms 连接避免 mount/unmount 竞态
### D. 后续如何避免问题
1. **前后端接口契约必须显式文档化**:新建/修改 API 时同步更新接口文档,字段名变更需两端对齐
2. **WebSocket 生命周期防御编程**:所有 `.close()` 调用前必须检查 `readyState`connect/disconnect 需幂等
3. **副作用清理必须防竞态**useEffect 中任何异步回调setInterval、setTimeout、event listener都需配合 `mounted` 或 AbortController
4. **上传后必须刷新列表**:任何创建资源的操作成功后,应主动重新拉取列表或返回完整资源对象写入本地状态
---
## 2026-04-28-22-55-15 — 建立代码编纂工作流
### A. 具体问题