Apollo Client Network Errors

本系列文以制作专案为主轴,纪录小弟学习React以及GrahQL的过程。主要是记下重点步骤以及我觉得需要记忆的部分,有觉得不明确的地方还请留言多多指教。

如果 Client 端的 GraphQL query 指令中的 fields 有误,向 Server 请求後 React 只会出现请求失败讯息。

像是执行以下 mutation:

const ADD_LIST = gql`
  mutation AddList($listTitle: String!) {
    addList(listTitle: $listTitle) {
      id
      name #这里应该是 title 才对
    }
  }
`;

Server 端应回传的 List 形别只有 title 栏位,没有 name 栏位,导致请求发送後会收到 status code 400 错误讯息:

但并不会显示是哪个 GraphQL 请求的哪个部分错误,这样要 debug 就伤脑筋了, 所以要另外设定 Apollo Client 的 Error handling 显示更精确的错误讯息。

Apollo Link


(图片来源: Apollo docs)

有关网路通讯以及GraphQL的错误讯息会需要利用 Apollo Link 来存取。

Apollo Link 用於设定每当 Apollo Client 执行 GraphQL 请求後的额外操作,可以串起一系列不同的 Link ,例如第一个 Link 将请求资讯写入 Log ,第二个 Link 在 Header 添加资讯,最後一个 Link 再向 Server 请求这样。

onError Link

Apollo 已经有提供一些现成的 Link 物件,其中一个是 onError 这个 Link,使用上会像这样:

import { onError } from "@apollo/client/link/error";

const link = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
      ),
    );

  if (networkError) console.log(`[Network error]: ${networkError}`);
});

这是官方范例,在出现 GraphQL 错误或网路通讯错误时显示讯息。

有了这个 Link 後,还不能直接应用到 Apollo Client 上,要先搭配发送请求给 Server 的 Link。

HttpLink

目前的 ApolloClient instance 长这样:

const client = new ApolloClient({
  uri: "http://localhost:4000/",
  cache: new InMemoryCache(),
});

在 ApolloClient 的设定中,可以用 uri 或 link 指定传送请求的 server,如果两者并存的话会以 link 优先。
相较 uri , link 可以制定更详细的请求设定。

使用 link 向 server 发送请求:

import { HttpLink } from "@apollo/client";

const link = new HttpLink({ uri: "http://localhost:4000/" });

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: link,
});

如果想串接更多 Link 模块,就需要用 HttpLink 负责最後向 Server 传送请求的工作。

串接多个 Link

接着要将错误讯息处理跟请求发送的 Link 串起来,设定给 ApolloClient。

Apollo Client 中的 from 方法,可以接收包含数个 Link 的阵列,包成一个 Link 物件使用。

const link = from([ Link1, Link2 , ... ,  terminatingLink]);

注意无论中间过程为何,负责向 Server 执行请求的 terminatingLink 必须放在阵列的最後一位。

将 ErrorLogLink 跟 terminatingLink 串接後给 ApolloClient 用:

import {
  ApolloClient,
  InMemoryCache,
  from,
  HttpLink,
} from "@apollo/client";
import { onError } from "@apollo/client/link/error";

const ErrorLogLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors)
    graphQLErrors.map(({ message, locations, path }) =>
      console.log(
        `[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`
      )
    );

  if (networkError) console.log(`[Network error]: ${networkError}`);
});

const RequestLink = new HttpLink({
  uri: process.env.REACT_APP_APOLLO_SERVER_URL,
});

const link = from([ErrorLogLink, RequestLink]);

const client = new ApolloClient({
  link: link,
  cache: new InMemoryCache(),
});

这样当执行了有问题的 GraphQL 请求後,就能在浏览器的 console 看见错误讯息,知道是哪个 field 出问题了:

References:


<<:  如何在图片和按钮上设定圆形 - 最终章

>>:  Day28 资料流重新导向I

OpenStack 部属工具 2

本系列文章同步发布於笔者网站 上一篇我们介绍了 DevStack 跟 MicroStack 这两个非...

Laravel 技术笔记 (四)【Query Builder 查询建构器】

介绍 在上一篇使用迁移定义好资料库的架构後,我们还需要学习如何与资料库互动,在 Laravel 中我...

< 关於 React: 开始打地基| props、state >

本章内容 prop的传递重点 宣告预设的props 如何使用prop this.state 从另外一...

GCP VPC防火墙

防火墙 GCP VPC防火墙规则,应用於给定的项目和网络,防火墙规则可以包含IPv4 IPv6 范围...

用 Python 畅玩 Line bot - 13:MongoDB 操作

连接资料库与资料表 连接到对应的资料库与资料表: import pymongo myclient =...