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

useMutation Hook错误与服务器抛出的错误信息不匹配问题咨询

useMutation Hook返回错误与服务器抛出信息不匹配的问题

问题现象

  • 客户端error link日志能正确输出服务器抛出的错误:[GraphQL error]: Message: Authentication required., Location: undefined, Path: undefined
  • 但使用useLazyQuery(或useMutation)时,打印返回的error得到的却是:Error: Response not successful: Received status code 400

相关代码

客户端Error Link配置

import { onError } from "@apollo/client/link/error";
const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
    graphQLErrors.forEach(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    );

  if (networkError) console.log(`[Network error]: ${networkError}`);
});
export const client = new ApolloClient({
  link: from([errorLink, authLink, uploadLink]),
  cache: new InMemoryCache()
});

客户端查询代码

const [signIn, { loading, error, data, networkStatus }] = useLazyQuery(
  PROFILE,
  { notifyOnNetworkStatusChange: true }
);

服务器端错误抛出代码

if (!user)
  throw new GraphQLError("Authentication required.", {
    extensions: { code: "UNAUTHORIZED" },
  });

原因分析

这是因为服务器返回了400 HTTP状态码,Apollo Client默认会将这类非200的响应判定为网络错误,而非GraphQL业务错误。虽然error link能从响应体中解析出graphQLErrors并打印,但useQuery/useMutation返回的error会优先指向网络错误对象,而非GraphQL错误信息。

解决方法

方法1:调整服务器端返回状态码(推荐)

按照GraphQL规范,即使存在业务错误,服务器也应该返回200 HTTP状态码,将错误信息放在响应体的errors字段中。这样Apollo Client会自动识别并将GraphQL错误映射到useQuery/useMutation的error对象里,无需额外处理。

方法2:客户端自定义错误处理

如果无法修改服务器配置,可以在error link中自定义逻辑,将GraphQL错误信息注入到组件可捕获的错误中:

import { onError } from "@apollo/client/link/error";
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
  if (graphQLErrors) {
    // 原打印逻辑保留
    graphQLErrors.forEach(({ message, locations, path }) =>
      console.log(`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`)
    );
    
    // 处理400状态码下的GraphQL错误
    if (networkError && graphQLErrors.length) {
      // 创建包含GraphQL错误信息的自定义错误
      const customError = new Error(graphQLErrors[0].message);
      customError.graphQLErrors = graphQLErrors;
      customError.code = graphQLErrors[0].extensions?.code;
      // 抛出错误,让组件的error字段捕获
      throw customError;
    }
  }
  if (networkError) console.log(`[Network error]: ${networkError}`);
});

之后在组件中就可以通过error.message拿到服务器抛出的“Authentication required.”,通过error.graphQLErrors拿到完整的错误数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:50:32