Apollo 错误处理 - 如何区分 503 和其他 5xx 错误

问题描述 投票:0回答:1

我有一个使用 Apollo 从 graphql 端点检索数据的 React 应用程序。

我设置了一个错误链接方法,如果从 GQL 返回 http 错误,则显示不同的消息,这对于 4xx 错误效果很好。但是,如果服务器因 5xx 错误而失败,我会在我的方法中收到通用的“无法获取”错误消息,但不会收到错误代码。

503 错误通常表明我们处于维护模式,因此我希望在收到 503 错误时能够显示不同的消息,而不是任何其他 5xx 错误。有没有办法调整我的错误处理来获取 5xx 错误的代码?我在传递给该方法的 errorResponse 中看不到任何明显的东西。

这是我的 onError 链接的截断版本:

  const errorLink = onError((errorResponse) => {
    const { graphQLErrors, networkError, operation } = errorResponse;

    // Doesn't work - networkError is null.
    if ((
      networkError?.statusCode === 503
    ) && !window.location.pathname.includes('maintenance-mode')
    ) {
      // [show maintenance mode page]
    }

    // This works.
    if (networkError?.statusCode === 401 && operation?.operationName !== 'auth') {
      // [redirect to login page]
    }

    // [...etc]
  });
reactjs error-handling apollo
1个回答
0
投票

在 Apollo 客户端中直接访问 HTTP 状态代码的一种方法是使用公开响应对象的自定义链接来扩展标准 HttpLink。这样,您可以直接从响应中访问状态代码。

这是从我之前的类似项目中手动编写的代码。

import { ApolloLink } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { createHttpLink } from '@apollo/client/link/http';

// Create a custom link that exposes the response object.
const customFetch = (uri, options) => {
  return fetch(uri, options).then(response => {
    // The status and statusText attributes are added to the response body here.
    return response.text().then(body => {
      return new Response(JSON.stringify({
        data: JSON.parse(body),
        status: response.status,
        statusText: response.statusText,
      }), {
        status: response.status,
        statusText: response.statusText,
      });
    });
  });
};

// Create HttpLink with custom fetch method
const httpLink = createHttpLink({
  uri: 'http://your-graphql-endpoint',
  fetch: customFetch,
});

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (networkError) {
    const { status } = JSON.parse(networkError.bodyText);

    if (status === 503) {
      // [show maintenance mode page]
    }
  }

  if (networkError?.statusCode === 401) {
    // [redirect to login page]
  }

  // [...etc]
});

// Combine your errorLink and httpLink
const link = ApolloLink.from([errorLink, httpLink]);

// Create your Apollo Client with the combined link
const client = new ApolloClient({
  link,
  cache: new InMemoryCache(),
});

在此示例中,我创建了一个由 Apollo 的 HttpLink 使用的自定义 fetch 函数。 fetch 函数将状态代码和状态文本添加到响应对象的正文中。这允许您直接从 onError 函数中的 networkError 访问状态代码。

希望我的回答能给你一点提示。

© www.soinside.com 2019 - 2024. All rights reserved.