处理 fetch 异常需分三类:网络层失败(如 typeerror)可重试;http 状态异常中 5xx 可重试、4xx 一般不重试;响应解析失败应主动 throw。超时须用 abortcontroller 配合 signal,检查 aborterror 统一处理。

处理 Fetch 请求的网络异常和超时,核心在于主动识别并分类错误类型,而不是依赖 fetch 自动抛错——因为 fetch 只在网络彻底失败(如断网、DNS 解析失败、CORS 拒绝)或被中止时才进 catch;而 404、500 等 HTTP 状态码默认不触发拒绝,必须手动判断。
区分三类常见异常并分别应对
实际开发中,请求失败大致分三类,每类需不同处理逻辑:
-
网络层失败:例如
TypeError: Failed to fetch、AbortError、DNS 错误。这类属于临时性问题,适合立即重试。 -
HTTP 状态异常:响应已收到但
res.ok === false。需进一步检查res.status:
• 500–599(服务端故障)可重试;
• 400–499(除 408 请求超时、429 频率限制)一般不重试,直接报错或提示用户修正输入。 -
响应体解析失败:比如
await res.json()报SyntaxError(非标准 JSON)。应主动throw,使其进入catch分支,统一走重试或降级流程。
用 AbortController 实现可控超时
fetch 本身没有超时机制,靠 Promise.race 包裹只是“假装取消”,底层请求仍在运行,可能造成资源堆积。正确做法是结合 AbortController:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 创建
controller = new AbortController(),把controller.signal传入 fetch 的options; - 用
setTimeout(() => controller.abort(), timeoutMs)设置硬性截止时间; - 在
catch中检查err.name === 'AbortError',即可确认是超时导致,并纳入可重试分支。
封装时用 if-else 明确控制流程
避免无限递归或死循环,每次重试前用计数器做显式判断:
- 当前尝试次数
- 已是最后一次尝试 → 不再等待,直接
throw err,交由上层统一兜底(如展示错误提示); - 响应成功(
res.ok === true)→ 立即return await res.json()或其他解析结果,退出整个重试流程。
基础封装示例(含超时与状态码判断)
以下是一个轻量但完整的结构示意,重点看条件分支如何串联:
async function fetchWithTimeout(url, options = {}, timeout = 5000, maxRetries = 2) {
for (let i = 0; i const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const res = await fetch(url, { ...options, signal: controller.signal });
clearTimeout(timeoutId);
if (!res.ok) {
if (res.status >= 500 && res.status if (i } else throw new Error(`HTTP ${res.status}`);
}
return await res.json();
} catch (err) {
if (err.name === 'AbortError' || err.name === 'TypeError') {
if (i }
throw err;
}
}
throw new Error('Request failed after retries');
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










