You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断捕获的异常由AbortController触发?React Hook问题排查

如何判断fetch捕获的异常是否由AbortController触发?

我用React结合TypeScript搭建了一个简易博客站点,编写了自定义Hook useFetch,在useEffect钩子中实现数据请求。添加setTimeout验证AbortController功能时,发现fetch请求在获取数据后依然进入catch分支,报错信息为"signal is aborted without reason",想知道如何区分该异常是否由AbortController触发。


判断方法

fetch被AbortController中止时抛出的错误属于DOMException类型,且带有特定标识,我们可以通过以下属性判断:

  • 检查错误的name属性:中止错误的name固定为'AbortError'
  • 部分环境下可检查code属性:比如Chrome中code为'ABORT_ERR'或数值20(DOM错误码)

TypeScript代码示例

在useFetch的catch逻辑中加入判断:

import { useEffect, useState } from 'react';

function useFetch<T>(url: string) {
  const [data, setData] = useState<T | null>(null);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    const controller = new AbortController();
    const { signal } = controller;

    const fetchData = async () => {
      try {
        const response = await fetch(url, { signal });
        if (!response.ok) throw new Error(`请求失败: ${response.status}`);
        const result = await response.json() as T;
        setData(result);
      } catch (err) {
        // 断言为DOMException类型,针对AbortError做处理
        const error = err as DOMException;
        if (error.name !== 'AbortError') {
          // 非中止类错误,才更新错误状态
          setError(error);
        }
        // 中止错误直接忽略,避免组件卸载后更新状态导致警告
      }
    };

    fetchData();

    // 组件卸载或依赖变化时中止请求
    return () => controller.abort();
  }, [url]);

  return { data, error };
}

补充说明

出现"signal is aborted without reason"的原因通常是:组件卸载或者useEffect依赖项更新时,AbortController的abort()被调用,此时即使请求已经完成,signal已中止的状态依然会让fetch抛出错误。这种情况下我们只需要识别并忽略该错误即可,无需作为业务错误处理。


内容的提问来源于stack exchange,提问作者Eshada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:14:58