20260429_231526-fix: upload field mismatch, WebSocket StrictMode crash, project list refresh after upload
This commit is contained in:
26
工程分析/经验记录.md
26
工程分析/经验记录.md
@@ -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` ref,cleanup 时置 `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. 具体问题
|
||||
|
||||
Reference in New Issue
Block a user