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

使用fetch时,如何在react-query中正确定义自定义错误类型?

React Query useQuery 实现类型安全的自定义 Fetch 错误方案

如果你用原生 Fetch 想给 useQuery 做类型正确的自定义错误,同时让 React Query 自动推断类型(不手动指定泛型),可以按下面的步骤来:

1. 定义带状态码的自定义错误类

先搞一个继承自 Error 的类,专门存响应状态码和相关信息,保证类型明确:

class FetchError extends Error {
  constructor(
    message: string,
    public status: number,
    public response?: Response
  ) {
    super(message);
    this.name = 'FetchError';
    // 修复原型链,保证 instanceof 判断准确
    Object.setPrototypeOf(this, FetchError.prototype);
  }
}

2. 封装类型安全的 Fetch 请求函数

把 Fetch 逻辑封装成一个函数,请求失败(非 2xx 状态)时抛出上面的自定义错误,同时指定返回数据的类型:

async function fetchJson<T>(url: string): Promise<T> {
  const res = await fetch(url);

  if (!res.ok) {
    // 读取响应里的错误信息,没有的话用状态码提示
    const errorMsg = await res.text() || `请求失败,状态码:${res.status}`;
    throw new FetchError(errorMsg, res.status, res);
  }

  // 解析 JSON 并指定返回类型 T
  return res.json() as Promise<T>;
}

这里的泛型 T 用来定义接口返回的数据结构,请求出错时抛出的 FetchError 会被 React Query 自动捕获,类型也会跟着推断出来。

3. 在 useQuery 里直接用,自动推断错误类型

现在用这个封装好的函数写 useQuery,不用手动指定泛型,React Query 会自动识别错误类型是 FetchError,你可以直接在 useErrorBoundary 里访问 status:

// 先定义你的数据类型
type UserData = {
  id: number;
  username: string;
  email: string;
};

const { data, isLoading, error } = useQuery(
  ['user-data'],
  () => fetchJson<UserData>('https://api.example.com/user'),
  {
    useErrorBoundary: (err) => {
      // 这里 err 自动推断为 FetchError,直接用 status 没问题
      return err.status >= 500;
    }
  }
);

// 如果要在组件里处理错误,也能安全访问 status
if (error instanceof FetchError) {
  console.log('错误状态码:', error.status);
}

额外处理网络层面的错误

如果要处理 Fetch 本身失败的情况(比如断网、域名不存在),可以在封装函数里加 try/catch:

async function fetchJson<T>(url: string): Promise<T> {
  try {
    const res = await fetch(url);

    if (!res.ok) {
      const errorMsg = await res.text() || `请求失败,状态码:${res.status}`;
      throw new FetchError(errorMsg, res.status, res);
    }

    return res.json() as Promise<T>;
  } catch (err) {
    // 处理网络错误,给个状态码 0 标识
    if (err instanceof Error) {
      throw new FetchError(err.message, 0);
    }
    throw new FetchError('未知错误', 0);
  }
}

这样不管是 HTTP 错误还是网络错误,抛出的都是类型明确的 FetchError,React Query 都能正确推断,你在任何错误处理逻辑里都能安全访问 status 属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 06:50:33