首页
/ axios 请求只报泛化 Network Error:如何为网络错误分类并输出详细原因

axios 请求只报泛化 Network Error:如何为网络错误分类并输出详细原因

2026-09-08 16:14:42作者:薛曦旖Francesca

axios 默认对大量不同的网络故障抛出同一个 "Network Error" 消息:断网、DNS 解析失败、服务器拒绝连接、CORS 拦截、请求超时,在 catch 里看起来几乎一样,调试时无法区分根因。本场景的目标是:在 axios 上挂一个响应拦截器,对错误做分类,给每个错误对象重写 error.code(如 ERR_TIMEOUTERR_DNS_FAILURE)并新增一个 error.detailedMessage 字段输出可读原因。仓库中的 examples/improved-network-errors.mdexamples/network_enhanced.js 提供了完整的方案与实现,按浏览器和 Node.js 两种环境均可使用。

前提只需安装 axios:

npm install axios

先弄清:为什么 axios 只报泛化错误

查阅 官方错误处理文档 的错误码表,与网络故障相关的有两个关键点:

  • ERR_NETWORK:网络类问题。在浏览器中,这个错误还可能由 CORS 或 Mixed Content 策略违规引起。文档明确指出:浏览器不允许 JS 代码澄清由安全问题引起的错误真实原因,需要自行查看控制台。
  • 超时默认报 ECONNABORTED;只有设置 transitional.clarifyTimeoutError: true 后才会报 ETIMEDOUT,这样超时错误才能和其他中断区分开。

也就是说,axios 本身的错误对象信息有限(浏览器安全限制决定了这一点),要输出详细原因,需要在业务层基于 error.codeerror.message 和响应状态码做二次分类。

方案:响应拦截器 + 错误增强函数

examples/improved-network-errors.md 描述的机制:

  1. axios.create(config) 创建实例;
  2. 通过 client.interceptors.response.use() 注册响应拦截器,在拒绝分支里捕获错误(拦截器机制见 Interceptors 文档);
  3. 拦截器调用 enhanceNetworkError(error):根据 error.codeerror.messageerror.response.status 判断错误类型,改写 error.code,挂上新字段 error.detailedMessage,然后重新 throw 出去。

完整实现见仓库中的 examples/network_enhanced.js,核心代码如下:

import axios from 'axios';

function enhanceNetworkError(error) {
  // when Offline (no internet)
  if (typeof navigator !== 'undefined' && !navigator.onLine) {
    error.code = 'ERR_NO_INTERNET';
    error.detailedMessage =
      'No internet connection detected. Please check your connection and try again.';
  }

  // when DNS failure occurs (invalid domain)
  else if (error.code === 'ENOTFOUND' || /dns/i.test(error.message)) {
    error.code = 'ERR_DNS_FAILURE';
    error.detailedMessage =
      'Unable to reach the requested domain. Please verify the URL or your network settings.';
  }

  // when Connection refused by server
  else if (error.code === 'ECONNREFUSED' || /refused/i.test(error.message)) {
    error.code = 'ERR_CONNECTION_REFUSED';
    error.detailedMessage =
      'Connection was refused by the server. It may be temporarily unavailable.';
  }

  // when Request timeout happens
  else if (error.code === 'ETIMEDOUT' || /timeout/i.test(error.message)) {
    error.code = 'ERR_TIMEOUT';
    error.detailedMessage = 'The request took too long to respond. Please try again later.';
  }

  // when CORS restriction happens (for browser only)
  else if (/CORS/i.test(error.message)) {
    error.code = 'ERR_CORS_BLOCKED';
    error.detailedMessage = 'The request was blocked due to cross-origin restrictions.';
  }

  // when Server-side error occurs
  else if (error.response && error.response.status >= 500) {
    error.code = 'ERR_SERVER';
    error.detailedMessage = 'A server-side issue occurred. Please try again later.';
  }

  // when Client-side error occurs
  else if (error.response && error.response.status >= 400) {
    error.code = 'ERR_CLIENT';
    error.detailedMessage = 'A client-side error occurred. Please check your request.';
  }

  //  when unknown network issue occurs
  else {
    error.code = 'ERR_NETWORK_GENERIC';
    error.detailedMessage =
      'A network issue occurred. Please check your connection or try again later.';
  }

  return error;
}

export function createEnhancedClient(config = {}) {
  const client = axios.create(config);

  client.interceptors.response.use(
    (response) => response,
    (error) => {
      throw enhanceNetworkError(error);
    }
  );

  return client;
}

export default enhanceNetworkError;

分类规则按 if/else 链的先后顺序匹配(先命中先归类):

判断条件 归类 code detailedMessage 含义
navigator.onLinefalse(浏览器) ERR_NO_INTERNET 无网络连接
error.code === 'ENOTFOUND' 或 message 含 dns ERR_DNS_FAILURE 域名无法解析
error.code === 'ECONNREFUSED' 或 message 含 refused ERR_CONNECTION_REFUSED 服务器拒绝连接
error.code === 'ETIMEDOUT' 或 message 含 timeout ERR_TIMEOUT 请求超时
message 含 CORS(浏览器) ERR_CORS_BLOCKED 跨域被拦截
error.response.status >= 500 ERR_SERVER 服务端错误
error.response.status >= 400 ERR_CLIENT 客户端错误
以上都不满足 ERR_NETWORK_GENERIC 未识别的网络问题

注意 5xx 的判断在 4xx 之前,因此 500 以上归类为 ERR_SERVER,400–499 归类为 ERR_CLIENT

使用与验证

createEnhancedClient() 创建客户端即可,之后所有请求的错误都会带上分类信息。以下示例中的 baseURL 是文档示例值,替换为你自己的接口地址:

const api = createEnhancedClient({ baseURL: 'https://example.com' });

api
  .get('/data')
  .then((res) => console.log(res.data))
  .catch((err) => {
    console.error(err.code);            // e.g., ERR_TIMEOUT
    console.error(err.detailedMessage); // e.g., "The request took too long to respond."
  });

验证方式:发起一个必然失败的请求(超时、错误域名、断网均可),在 catch 中打印 err.codeerr.detailedMessage,能按上表输出对应分类即说明拦截器生效。上面代码块中的两个 // e.g., 值是文档给出的示例输出,不是固定预期。

若想在分类前先检查 axios 原始错误,错误处理文档 给出了三分支判断:error.response 存在表示服务器已响应但状态码不在 2xx 范围;error.request 存在表示请求已发出但没有收到响应(浏览器中是 XMLHttpRequest 实例,Node.js 中是 http.ClientRequest 实例);两者都没有则是请求设置阶段出错。错误对象还支持 error.toJSON() 获取完整信息,含 messagenamestackconfigcodestatus 字段。

让超时错误可靠命中超时分支

enhanceNetworkError 的超时分支依赖 ETIMEDOUT(或 message 含 timeout)。而 axios 默认超时报的是 ECONNABORTED。按 官方超时处理文档,应在请求配置(或 createEnhancedClient 传入的 config)中设置 timeout 并开启 clarifyTimeoutError

const response = await axios.get("https://example.com/data", {
  timeout: 5000, // 5 seconds
  transitional: {
    // set to true if you prefer ETIMEDOUT over ECONNABORTED
    clarifyTimeoutError: true,
  },
});

官方文档同时提示:生产环境应始终设置 timeout,否则卡住的请求可能无限挂起。clarifyTimeoutError 的含义与默认值(false)见 request-config 文档

限制与边界

  • 浏览器中的 CORS/Mixed Content 无法可靠识别:官方文档明确说明浏览器不允许 JS 代码澄清这类安全错误的真实原因,要定位需查看控制台。/CORS/i.test(error.message) 这条规则只在错误 message 中确实含有 CORS 字样时才命中,不能保证覆盖所有跨域失败。
  • 离线检测只在浏览器生效ERR_NO_INTERNET 分支依赖 navigator.onLine,Node.js 环境中该分支不成立,断网会落到后续规则或 ERR_NETWORK_GENERIC
  • 分类顺序固定if/else 链保证先命中的规则优先(如离线判断在 DNS 判断之前),不要随意调整顺序。
  • 该方案是业务层封装:它改写的是你应用持有的错误对象,axios 抛出的原始错误(ERR_NETWORKECONNABORTED 等)行为不变,其他使用 axios 的模块不受此拦截器影响。

参考文件

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391