docs(changelog-v2): 任务看板打开弹「获取看板X失败」toast = 前端竞态重复请求被取消, 通知 mmg(后端实测全200健康无改动)
这个提交包含在:
父节点
2817285cf4
当前提交
5d531063d9
@ -0,0 +1,100 @@
|
||||
# 【前端 BUG·管理后台】任务看板打开弹「获取看板详情/任务/成员失败」红 toast = 前端竞态重复发请求 + 取消被误报错
|
||||
|
||||
> **关联**: 无工单(前端 bug 走 changelog 通知 mmg)
|
||||
> **服务**: 前端 hl-ui(**后端零改动**)| **提报时间**: 2026-06-05
|
||||
>
|
||||
> **存放目录**: `changelogs-v2/2026-06/`
|
||||
> **影响范围**: 管理后台「任务看板」`/task/boards`(看板列表 / 看板详情视图)
|
||||
> **类型**: 前端竞态 bug(mmg 修),**后端实测全 200 健康无需改动**
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ 关键说明
|
||||
|
||||
打开任务看板时弹出红色错误 toast「**获取看板详情失败 / 获取看板任务失败 / 获取看板成员失败**」,**但看板数据其实正常加载出来了**(公司看板、各状态列、任务卡片都在)。
|
||||
|
||||
**根因 = 前端竞态,不是后端故障。** 看板组件挂载时对**同一个数据接口重复发请求**(`tasks` 发 3 次、`members` 发 2 次、`detail` 视时序也会重发),多余的在飞请求被前端 `AbortController` **主动取消**(浏览器 `net::ERR_ABORTED`)。前端 `.catch()` **没有把「请求被取消」和「请求真失败」区分开**,于是把取消也当成失败弹了红 toast。
|
||||
|
||||
后端侧:凡是被允许跑完的请求**全部返回 200**(看板列表/详情/任务/成员/状态 + token refresh,curl 80+ 次 + 真浏览器多轮复现,零服务端失败)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 实证(真浏览器 DevTools Network,刚登录 token 全新,硬刷新复现)
|
||||
|
||||
打开 `/task/boards`(公司看板 `2022226454376366081`)后的请求序列:
|
||||
|
||||
| # | 请求 | 结果 |
|
||||
|---|---|---|
|
||||
| 1 | `GET /admin/task/boards`(看板列表) | **200** ✅ |
|
||||
| 2 | `GET /admin/task/board/{id}`(看板详情,含 statuses) | **200** ✅ |
|
||||
| 3 | `GET /admin/task/board/{id}/tasks` | **FAILED `net::ERR_ABORTED`** ❌ |
|
||||
| 4 | `GET /admin/task/board/{id}/tasks` | **200** ✅(同一接口重发,成功)|
|
||||
| 5 | `GET /admin/task/board/{id}/members` | **200** ✅ |
|
||||
| 6 | `GET /admin/task/board/{id}/tasks` | **FAILED `net::ERR_ABORTED`** ❌ |
|
||||
| 7 | `GET /admin/task/board/{id}/members` | **200** ✅(同一接口重发)|
|
||||
|
||||
要点:
|
||||
- `tasks` 接口被触发 **3 次**(2 次被取消、1 次成功);`members` 触发 **2 次**;`detail` 偶发重发被取消时就弹「获取看板详情失败」。
|
||||
- `net::ERR_ABORTED` 是**客户端主动取消**(不是 4xx/5xx,服务端从没收到失败结果),典型来自 axios cancel / `AbortController.abort()` / 组件重渲染或重复触发同一 fetch。
|
||||
- 浏览器 console **0 个 error**(说明取消已被 catch 捕获),但 catch 里仍调用了错误 toast。
|
||||
|
||||
后端实测对照(均 200,有数据):
|
||||
|
||||
```
|
||||
GET /admin/task/boards -> 200, 看板列表
|
||||
GET /admin/task/board/2022226454376366081 -> 200, 详情含 4 个 statuses
|
||||
GET /admin/task/board/2022226454376366081/tasks -> 200, 任务分组
|
||||
GET /admin/task/board/2022226454376366081/members -> 200, []
|
||||
GET /admin/task/board/2022226454376366081/statuses-> 200, 4 条
|
||||
POST /admin/auth/refresh (真 refreshToken) -> 200(连打 30 次全 200)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 前端修法(mmg)
|
||||
|
||||
### 2.1 必修:catch 里放过「被取消」的请求,别弹错误 toast
|
||||
|
||||
错误处理里先判断是否为取消,是则**静默 return**,不弹 toast:
|
||||
|
||||
```js
|
||||
import axios from 'axios'
|
||||
// ...
|
||||
.catch((e) => {
|
||||
// 请求被取消(组件重渲染/重复触发抢占)是预期行为,不是错误
|
||||
if (axios.isCancel(e) || e?.code === 'ERR_CANCELED' || e?.name === 'CanceledError') return
|
||||
ElMessage.error('获取看板任务失败') // 只有真失败才提示
|
||||
})
|
||||
```
|
||||
|
||||
三处都要加:获取看板详情 / 获取看板任务 / 获取看板成员的 catch。
|
||||
|
||||
### 2.2 根治:去掉对同一接口的重复触发
|
||||
|
||||
`tasks` 发 3 次、`members` 发 2 次,说明同一 fetch 被多个来源同时触发(常见:`onMounted` 触发一次 + `watch(boardId)` 触发一次 + 默认「优先级/状态」筛选 radio 又触发一次)。建议:
|
||||
|
||||
- 数据加载**只保留单一触发源**(推荐由 `watch(boardId, { immediate: true })` 统一触发,去掉 `onMounted` 里的重复拉取);
|
||||
- 或对每类请求维护一个 `AbortController`,重发前先 `abort()` 旧的——**但这种「主动取消」必须配合 §2.1,把取消视为正常、不报错**。
|
||||
|
||||
### 2.3 注意(与本 bug 无关、但同页常见)
|
||||
|
||||
看板有实时通道(`/ws/task/info` + `/admin/task/board/ws-doc`)。若 WS 推送后又触发整页重新拉取,也会放大上面的「重复请求 + 取消」现象,一并按 §2.1/§2.2 处理。
|
||||
|
||||
---
|
||||
|
||||
## 3. 后端状态(无需改动)
|
||||
|
||||
- 任务看板全部读接口(list / detail / tasks / members / statuses)实测 200,数据正确。
|
||||
- `POST /admin/auth/refresh`:网关已在 `JwtAuthFilter.SKIP_URLS` 白名单放行,带过期 access token + 真 refreshToken 实测 200,20 并发全 200。
|
||||
|
||||
### 3.1 附注:你截图里 `refresh` 的 502 是「另一桩、瞬时」
|
||||
|
||||
你之前截图 Network 里 `refresh` 显示 **502**,那是**独立的瞬时事件**:当时会话 access token 已过期 → 前端自动调 `/admin/auth/refresh` 续签 → 恰好撞上测试服 user-service(双实例 8081/8181)部署/重启抖动,网关 LB 轮到正在重启的实例返 502。**当前 30+ 次 refresh 全 200,复现不出,不是看板代码缺陷**,无需前端改动;若再遇到,刷新页面即恢复。
|
||||
|
||||
---
|
||||
|
||||
## 4. 关联
|
||||
|
||||
- 后端负责人:@wx(已实测确认后端健康,无改动)
|
||||
- 前端对接(本 bug 修复):**mmg**
|
||||
- 复现路径:登录管理后台 → 任务看板(`/task/boards`)→ 打开「公司看板」即弹失败 toast,但数据正常。
|
||||
正在加载...
x
在新工单中引用
屏蔽一个用户