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

使用SWR Mutation+Axios+Next.js时出现未处理运行时AxiosError

解决SWR Mutation结合Axios在Next.js中触发错误模态框的问题

问题背景

使用SWR Mutation结合Axios实现Next.js登录功能时,明明接口已有响应,却会弹出Next.js的错误模态框;改用Fetch API实现则无此问题。相关代码如下:

fetch.ts

export const loginFetch = async (
    url,
    { arg }
) => {
     try {
// with fetch no problem but with axios show this modal next error
    const data = await BASE_URL.post<APIAuthLogin>(url, arg);
  
    return data;
}
}

form.tsx

const { trigger, error } = useMutation("/auth/login", loginFetch);

    async function onLogin(datos: AuthLogin) {
        await trigger(datos);
    }

问题根源

  1. Axios与Fetch的错误处理逻辑差异:Axios默认会对非2xx状态码的响应抛出异常,而Fetch API不会——它需要开发者手动通过response.ok判断请求是否成功。当登录接口返回401(账号密码错误)这类非2xx状态码时,Axios会直接抛出错误,被SWR Mutation捕获后触发Next.js的错误边界。
  2. 缺少错误捕获逻辑:当前loginFetch的try块没有对应的catch处理,导致Axios抛出的错误直接向上传递,触发全局错误模态框。
  3. 返回值结构不一致:Axios返回的是包含data、status等字段的完整响应对象,而Fetch通常返回解析后的纯数据,这也可能导致SWR处理数据时的行为差异。

解决方案

方案1:添加错误捕获并对齐Fetch返回格式

修改fetch.ts中的loginFetch函数,捕获Axios错误并提取纯数据返回,和Fetch的行为对齐:

export const loginFetch = async (url, { arg }) => {
  try {
    const response = await BASE_URL.post<APIAuthLogin>(url, arg);
    // 返回Axios响应中的纯数据,和Fetch返回格式一致
    return response.data;
  } catch (error) {
    // 区分响应错误和网络错误,自定义错误信息
    if (error.response) {
      // 接口有响应但状态码非2xx,抛出包含响应数据的错误
      throw new Error(JSON.stringify(error.response.data));
    } else {
      // 处理网络异常等情况
      throw new Error(error.message);
    }
  }
};

方案2:修改Axios配置,禁用非2xx状态码拦截

如果希望Axios和Fetch一样不对非2xx状态码抛出错误,可以修改Axios实例配置:

// 创建BASE_URL实例时添加配置
const BASE_URL = axios.create({
  // ...其他配置
  validateStatus: (status) => {
    // 所有状态码都视为成功,不抛出错误
    return true;
  }
});

之后在loginFetch中手动判断状态码:

export const loginFetch = async (url, { arg }) => {
  const response = await BASE_URL.post<APIAuthLogin>(url, arg);
  // 手动判断状态码,非2xx则抛出错误
  if (response.status >= 400) {
    throw new Error(JSON.stringify(response.data));
  }
  return response.data;
};

方案3:组件内捕获错误,避免触发全局错误边界

在form.tsx的登录函数中直接捕获错误,用自定义逻辑处理而非触发Next.js全局错误模态框:

async function onLogin(datos: AuthLogin) {
  try {
    await trigger(datos);
  } catch (error) {
    // 自定义错误处理,比如显示本地错误提示
    console.error('登录失败:', error);
    // setLoginError(error.message); // 可结合状态显示错误信息
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:32:33