Axios 错误处理深度解析:AxiosError 结构、错误码、超时区分与敏感信息脱敏 📅 发布时间:2026/9/5 19:49:50 👁 浏览次数: Axios 错误处理深度解析AxiosError 结构、错误码、超时区分与敏感信息脱敏【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axiosaxios 默认在请求失败时让 Promise 被 reject而失败的具体形态由AxiosError对象承载。本文基于官方文档docs/fr/pages/advanced/error-handling.md并结合 axios 源码完整解析 axios 抛出的错误结构message、code、status、config、request、response等字段、axios 内部识别的全部错误码及其在源码中的产生位置以及validateStatus自定义判定、timeout超时错误区分ECONNABORTED与ETIMEDOUT、畸形 HTTP(S) URL 的严格校验还有通过toJSON()序列化错误和使用redact配置避免密钥泄漏的实战方案。读完本文你可以在浏览器与 Node.js 环境下编写结构清晰、可区分超时/网络/取消等错误类型、且不会在日志中泄露凭据的错误处理代码。AxiosErroraxios 错误的统一载体axios 抛出的绝大多数错误都是AxiosError实例由原生Error派生文档给出的通用结构如下属性定义message错误消息与失败状态码的简短摘要。name标识错误来源。来自 axios 的错误该值始终为AxiosError。stack提供错误的调用堆栈。config请求发起时 axios 的配置对象包含用户为请求/实例设置的各项配置。code代表被 axios 识别的错误类型具体取值见下一节的错误码表。statusHTTP 响应状态码。此外AxiosError实例还带有一个布尔标记isAxiosError true这正是axios.isAxiosError(error)的判定依据。从源码看isAxiosError.js 中该函数只做一次属性检查export default function isAxiosError(payload) { return utils.isObject(payload) payload.isAxiosError true; }而在 AxiosError.js 的构造函数中各字段被显式挂到实例上第 160–168 行this.name AxiosError; this.isAxiosError true; code (this.code code); config (this.config config); request (this.request request); if (response) { this.response response; this.status response.status; }可以据此推断出文档中三个错误分支与源码字段的对应关系只有拿到服务端响应response时才设置status只有请求已发出但无响应时request才有值而配置阶段的错误通常既没有request也没有response只留下config与message。axios 内部识别的错误码code文档列出了 axios 可识别的全部错误码。这些错误码以静态属性形式定义在 AxiosError.js 中可统一通过AxiosError.ERR_NETWORK等引用错误码含义ERR_BAD_OPTION_VALUEaxios 配置中提供了无效或不受支持的值。ERR_BAD_OPTIONaxios 配置中提供了无效的选项。ECONNABORTED通常表示请求超时除非设置了transitional.clarifyTimeoutError或被浏览器/插件中止。ETIMEDOUT请求超过了 axios 默认超时时间。需将transitional.clarifyTimeoutError设为true否则抛出的仍是通用的ECONNABORTED。ERR_NETWORK网络类问题。在浏览器中CORS 违规或混合内容mixed content也可能导致此错误出于安全考虑浏览器不允许 JS 得知真实原因请查看控制台。ERR_FR_TOO_MANY_REDIRECTS请求被重定向的次数超过了 axios 配置中指定的最大值。ERR_DEPRECATED使用了 axios 中已被弃用的功能或方法。ERR_BAD_RESPONSE响应无法被正确解析或格式不符合预期通常对应5xx状态码。ERR_BAD_REQUEST请求格式不符合预期或缺少必需参数通常对应4xx状态码。ERR_CANCELED功能或方法被用户通过 AbortSignal或 CancelToken显式取消。ERR_NOT_SUPPORT当前 axios 运行环境不支持该功能或方法。ERR_INVALID_URLaxios 请求提供了无效的 URL。ERR_FORM_DATA_DEPTH_EXCEEDED序列化params或表单数据时某对象深度超过了配置的maxDepth默认限制 100 层。可参考 请求配置文档 中的paramsSerializer与formSerializer说明。源码中可以找到几个代表性错误码的产生点ERR_BAD_REQUEST/ERR_BAD_RESPONSE由 settle.js 在响应判定失败时抛出状态码 4xx/5xx 与错误码的对应关系即在此处确定reject(new AxiosError( Request failed with status code response.status, response.status 400 response.status 500 ? AxiosError.ERR_BAD_REQUEST : AxiosError.ERR_BAD_RESPONSE, response.config, response.request, response ));ERR_INVALID_URL由 buildFullPath.js 中的assertValidHttpProtocolURL抛出详见下文畸形 URL一节此外 fromDataURI.js 在解析非法 data URI 时也会使用该错误码。ERR_FORM_DATA_DEPTH_EXCEEDED分别由 toFormData.js 与 formDataToJSON.js 在递归序列化超过maxDepth时抛出。捕获与处理错误response / request / config 三分支axios 的默认行为是请求失败时 reject Promise。捕获错误后推荐的判断顺序是先查error.response再查error.request最后处理配置阶段的错误。这是文档给出的标准示例axios.get(/user/12345).catch(function (error) { if (error.response) { // 请求已发出且服务端返回了非 2xx 的状态码 console.log(error.response.data); console.log(error.response.status); console.log(error.response.headers); } else if (error.request) { // 请求已发出但未收到任何响应 // 浏览器中 error.request 是 XMLHttpRequest 实例 // Node.js 中是 http.ClientRequest 实例 console.log(error.request); } else { // 请求配置阶段就发生了错误 console.log(Error, error.message); } console.log(error.config); });这个三分支结构之所以可靠是因为它直接对应AxiosError构造函数的赋值逻辑response分支意味着响应已存在服务端返回了非 2xxrequest分支意味着请求已挂到实例上但响应缺失网络中断、超时、CORS 等否则就是配置校验、URL 解析等问题此时只有config和message可用。在 Node.js 环境中http.js 适配器抛错时会把原生http.ClientRequest作为request传入浏览器中则由 xhr.js 传入XMLHttpRequest实例。使用 validateStatus 自定义何为失败axios 的默认判定是status 200 status 300时 resolve否则 reject。通过配置项validateStatus可以覆盖这一条件自行决定哪些 HTTP 状态码应当触发错误axios.get(/user/12345, { validateStatus: function (status) { return status 500; // 只有状态码小于 500 才视为成功 }, });默认实现在 defaults/index.js 中定义判定逻辑则在 settle.js 执行若validateStatus(response.status)返回真值则 resolve否则构造AxiosError并 reject。此外 mergeConfig.js 中还有一个transitional.validateStatusUndefinedResolves细节当请求级配置显式传入validateStatus: undefined且该过渡开关为false时会回退到实例级validateStatus这允许你用请求级配置覆盖实例默认值。处理超时ECONNABORTED 与 ETIMEDOUT 的区分当请求超过配置的timeout时axios 默认以ECONNABORTED拒绝 Promise。若希望获得更精确的ETIMEDOUT错误码需要设置transitional.clarifyTimeoutError: trueasync function fetchWithTimeout() { try { const response await axios.get(https://example.com/data, { timeout: 5000, // 5 秒 transitional: { // 若希望用 ETIMEDOUT 替代 ECONNABORTED设为 true clarifyTimeoutError: true, }, }); console.log(Response:, response.data); } catch (error) { if (axios.isAxiosError(error)) { if (error.code ECONNABORTED || error.code ETIMEDOUT) { console.error(Request timed out. Please try again.); return; } console.error(Axios error:, error.message); return; } console.error(Unexpected error:, error); } }源码层面transitional.js 显示clarifyTimeoutError的默认值是false因此不显式开启时超时一律是ECONNABORTED。浏览器适配器的request.ontimeout处理xhr.js体现了这一切换逻辑reject( new AxiosError( timeoutErrorMessage, transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED, config, request ) );Node.js 适配器 http.js 中的超时处理采用完全相同的三元表达式另外 composeSignals.js 在组合 AbortSignal 超时时直接抛出ETIMEDOUT可据此推断不同触发路径下错误码可能略有差异编写兜底逻辑时建议同时兼容ECONNABORTED与ETIMEDOUT。生产环境务必设置timeout否则被阻塞的请求可能永远处于挂起状态。相关配置项参见 请求配置文档 中的timeout与transitional.clarifyTimeoutError说明。畸形 HTTP(S) URLERR_INVALID_URL 的严格校验axios 会拒绝url或baseURL中协议后缺少//的http:/https:URL。例如https:example.com与https:/example.com不会被浏览器或 Node.js 的 URL 解析器静默修正而是直接抛出code为ERR_INVALID_URL的AxiosError。请使用https://example.com这类格式正确的 URL。错误消息会明确指出有问题的 URL例如Invalid URL https:example.com: missing // after protocol这一行为在 buildFullPath.js 中实现核心是一个正则与断言函数const malformedHttpProtocol /^https?:(?!\/\/)/i; function assertValidHttpProtocolURL(url, config) { if (typeof url string) { const normalizedURL normalizeURLForProtocolCheck(url); if (malformedHttpProtocol.test(normalizedURL)) { throw new AxiosError( Invalid URL ${JSON.stringify(redactSensitiveURLParts(normalizedURL))}: missing // after protocol, AxiosError.ERR_INVALID_URL, config ); } } }其中 normalizeURLForProtocolCheck.js 会先对齐 WHATWG URL 的预处理规则剔除前导空白字符并移除\t、\n、\r控制字符后再做协议检查防止通过控制字符绕过校验。安全动机这种严格校验能阻止畸形 URL 绕过baseURL拼接逻辑或 URL 白名单机制。更重要的是错误消息中对 URL 的展示做了系统性脱敏redactSensitiveURLParts保留协议、主机、路径与查询参数名使请求仍可被识别掩码凭据userinfo、查询参数值与 fragment 内容替换为[REDACTED ****]标记。之所以必须系统性掩码是因为AxiosError.message总是被toJSON()原样序列化进日志而配置中的redact选项只能清理config下的键值无法清理已经生成好的错误消息文本。单元测试 buildFullPath.test.js 验证了这一行为例如Invalid URL https:[REDACTED ****]api.example.com/v1?apikey[REDACTED ****]id[REDACTED ****]#token[REDACTED ****][REDACTED ****]: missing // after protocol序列化错误toJSON() 与 redact 脱敏配置使用toJSON()可以获得包含更多信息的错误对象快照axios.get(/user/12345).catch(function (error) { console.log(error.toJSON()); });从 AxiosError.js 的toJSON()实现可以看到返回对象包含标准字段message、name、stack、浏览器扩展字段description、fileName等以及 axios 特有字段config、code、status。为了避免把密钥从error.config中打进日志可以在请求配置里传入redact数组。调用AxiosError#toJSON()时任何深度的、大小写不敏感的同名配置键都会被替换为脱敏标记axios.get(/user/12345, { headers: { Authorization: Bearer token }, redact: [authorization] }).catch(function (error) { console.log(error.toJSON().config.headers.Authorization); // [REDACTED ****] });实现上toJSON()检测到config.redact是非空数组时会调用redactConfigAxiosError.js生成脱敏后的配置快照它把redact中的键统一转为小写后逐一匹配递归遍历普通对象与数组对AxiosHeaders实例先调用其toJSON()再处理并通过seen列表短路循环引用。命中键的值被替换为模块级常量REDACTED [REDACTED ****]。AxiosError.test.js 的toJSON redaction via config.redact测试组覆盖了完整语义redact未定义或为空数组时保持旧序列化行为顶层键、嵌套对象auth.password、proxy.auth.password、AxiosHeaders实例、对象数组内的键均可被正确掩码并且对继承的redact访问器与原型污染场景做了防护。小结可落地的错误处理清单结合文档与源码可归纳出如下可复制的错误处理实践用axios.isAxiosError(error)确认错误来源再按error.response→error.request→ 其他 的顺序三分支处理依赖error.code而非error.message文本做类型分发ERR_CANCELED取消、ETIMEDOUT/ECONNABORTED超时、ERR_NETWORK网络/CORS、ERR_BAD_REQUEST/ERR_BAD_RESPONSE4xx/5xx用validateStatus精确控制哪些状态码算失败例如把 404 视为正常空结果时返回status 500生产环境设置timeout并按需开启transitional.clarifyTimeoutError以获得可区分的ETIMEDOUT日志输出统一走error.toJSON()并对Authorization、token、password等键配置redact注意错误消息文本本身的脱敏只由 axios 在生成时完成如畸形 URL 场景redact无法回溯清理。【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考