错误处理模式
request-guard 的错误分两类:短路错误(请求未发出)和真实错误(请求发出后失败)。它们的处理出口不同,混用会踩坑。本页给出选型与共存模式。
⚡ 两类错误的本质区别
| 短路错误 | 真实错误 | |
|---|---|---|
| 请求是否发出 | ❌ 未发出 | ✅ 已发出 |
是否经过 axios.interceptors.response.use | ❌ 不经过 | ✅ 经过 |
| 触发能力 | duplicate block、circuitBreaker 熔断打开、duplicate 容量满 | retry 耗尽后返回的原始错误、网络错误、业务错误码 |
error.name | RequestGuard*Error | 原始错误名 |
短路错误不经过响应拦截器
duplicate block、cache evicted、circuitBreaker 熔断打开这类"请求未发出"的短路错误,不会进入 axios.interceptors.response.use 的错误处理,因为请求根本没发出去。duplicate ignore 命中不会产生错误,也不会进入 .catch();它返回的是永远 pending 的 Promise。
javascript
// ❌ 不可靠:短路错误不会进入这里
axios.interceptors.response.use(null, (error) => {
if (error.name === 'RequestGuardBlockedError') { Toast.show(error.message); }
return Promise.reject(error);
});🎯 统一处理出口选型
| 出口 | 适合场景 | 优势 | 局限 |
|---|---|---|---|
notify 回调 | guard 主动触发的用户提示(duplicate 命中、熔断拦截/状态变更) | 无需业务侧 catch,guard 触发的提示都能收口 | 只处理 guard 主动提示,真实网络/业务错误不通用进入 |
请求级 .catch | 按错误类型分支处理 | 用 error.name 精确判别,可改变后续逻辑 | 每个调用点都要写 |
| 响应拦截器 | 真实错误的统一处理 | 集中管理 | 收不到短路错误 |
👍 推荐组合
大多数项目推荐 notify(提示)+ 响应拦截器(真实错误) 双出口:
javascript
// 出口 1:notify 处理 guard 主动触发的用户提示
setupRequestGuard(axios, {
notify: (payload) => {
// duplicate ignore/block 命中、熔断拦截 都会进这里
Toast.show(payload.message);
}
});
// 出口 2:响应拦截器处理真实错误(短路错误不进这里)
axios.interceptors.response.use(
(response) => response,
(error) => {
// 这里只会收到真实错误(网络错误、4xx/5xx、retry 耗尽后的原始错误)
// 短路错误(RequestGuard*Error)不会进这里
return Promise.reject(error);
}
);如果某些调用点需要按错误类型走不同逻辑,再在请求级 .catch 里用 error.name 分支:
javascript
try {
await axios.post('/api/order', data);
} catch (error) {
switch (error.name) {
case 'RequestGuardBlockedError':
// block 命中,已被 notify 提示,这里可静默或额外处理
break;
case 'RequestGuardCircuitBreakerError':
// 熔断拦截,引导用户稍后重试
router.push('/maintenance');
break;
default:
// 真实错误,走业务统一处理
throw error;
}
}🔄 retry 耗尽后的错误语义
retry 重试耗尽后,返回的是原始错误(不是 guard 包装的错误),所以:
error.name是原始错误的 name(如AxiosError),不是RequestGuardRetryCancelledError- 响应拦截器能收到这个错误(因为请求确实发出过)
- retry 耗尽事件通过
retry.exhaustedlogger 事件观测,不触发 notify
RequestGuardRetryCancelledError 只在 clearState() 主动取消 waiting 状态的重试时抛出,属于短路错误语义。
🔗 与业务全局错误处理共存
如果你的项目已有全局错误处理(如响应拦截器里的统一 toast / 错误码路由),接入 guard 时注意:
- 短路错误不要在拦截器里处理——它们不经过拦截器。用
notify出口接住。ignore 命中不是错误,不会进入任何错误处理分支。 - 真实错误保持原流程——guard 不包装真实错误,你的拦截器逻辑无需改动。
- 避免重复提示——如果
notify已经提示了 block 命中,拦截器里的通用 toast 不要再对同一行为二次提示(短路错误本来就不会进拦截器,所以天然不冲突)。
📋 完整错误名一览
所有错误名及触发时机见 错误类型。

