错误边界仅捕获组件渲染、生命周期或构造函数中的 javascript 异常,不处理流式响应中的业务错误(如 token 耗尽);需在流解析时显式 throw 才能触发捕获,并配合拦截器、前置校验等分层防御。

错误边界(Error Boundary)本身不捕获流式响应中的业务错误,它只拦截 React 组件树在渲染、生命周期或构造函数中抛出的 JavaScript 异常。而 Token 耗尽这类后端业务错误,通常发生在 fetch 或 axios 发起的流式请求(如 ReadableStream、SSE、或分块传输)过程中,属于网络响应层面的问题,不会自动触发错误边界的 componentDidCatch 或 getDerivedStateFromError。
明确错误边界的适用范围
错误边界无法感知以下情况:
- fetch 请求返回 401/403 等 HTTP 状态码(这不是 JS 异常,而是合法响应)
- 流式读取中
reader.read()返回{ done: true, value: undefined }后的自然结束 - 后端主动推送的业务错误消息(如
{"code": "TOKEN_EXPIRED", "msg": "token 已失效"}) - AbortError、NetworkError 等原生 DOM 异常——除非你在组件内部 手动 throw,否则错误边界不会介入
真正有效的处理路径:在数据消费层主动识别并抛出
要让错误边界起作用,必须把业务错误“转化”为组件内可捕获的 JS 异常。关键是在解析流数据时做判断,并在发现 Token 耗尽等条件时 显式 throw:
- 使用
Response.body.getReader()读取流,在每次result.value解析后检查响应体内容 - 若解析出
code === "TOKEN_EXPIRED"或status === 401,立即throw new Error("Token expired") - 该异常若发生在
useEffect、render或自定义 Hook 的同步执行路径中,且该组件被错误边界包裹,就会被捕获
配合状态管理实现降级 UI 与无感恢复
仅靠错误边界显示 fallback UI 不够,还需联动业务逻辑:
- 错误边界捕获后,调用
onTokenExpired()回调,触发 token 刷新流程 - 刷新成功后,通过 ref 或 context 通知流消费者重试请求(避免整页刷新)
- 在 fallback UI 中不只显示“加载失败”,而是展示 正在刷新凭证…,保持用户感知连贯
- 对重复触发的 token 刷新加锁,防止并发请求导致 429 或状态混乱
更健壮的做法:分层防御,不依赖单一机制
错误边界是兜底,不是主力:
- HTTP 拦截器(如 axios.interceptors.response)应优先拦截 401,直接触发刷新,避免错误流入 React 渲染层
- 流式请求前,先校验本地 token 有效期(如检查 exp 字段),提前拒绝无效请求
- 服务端返回结构需统一,确保所有业务错误都带
code字段,前端可集中判别 - 错误边界仅用于捕获那些“漏网”的、未被拦截器/前置校验覆盖的异常渲染场景










