【问题标题】:Apollo client mutation error handlingApollo 客户端突变错误处理
【发布时间】:2017-09-14 06:14:45
【问题描述】:

我在服务器上使用 GraphQL 和 mongoose。

当发生验证错误时,GraphQL 突变会发送状态码为 200 的响应。在客户端,响应如下所示:

{
  "data": null,
  "errors": [{
    "message": "error for id...",
    "path": "_id"
  }]
}

我想使用 apollo-client 突变承诺的 catch 功能访问验证错误。比如:

      this.props.deleteProduct(this.state.selectedProductId).then(response => {
         // handle successful mutation
      }).catch(response => {
         const errors = response.errors; // does not work
         this.setState({ errorMessages: errors.map(error => error.message) });
      });

如何做到这一点?

【问题讨论】:

  • 通过创建Error 实例尝试使用throw 语句

标签: graphql apollo apollo-client


【解决方案1】:

注意:这个答案(可以说是整个问题)现在已经过时了,因为在 Apollo Client 的最新版本中,catch 中出现了突变错误。

来自突变的 GraphQL 错误当前显示在 then 内部响应的 errors 字段中。我认为肯定有人声称它们应该出现在catch 中,但这是来自GitHunt 的突变的sn-p:

// The container
const withData = graphql(SUBMIT_REPOSITORY_MUTATION, {
  props: ({ mutate }) => ({
    submit: repoFullName => mutate({
      variables: { repoFullName },
    }),
  }),
});

// Where it's called
return submit(repoFullName).then((res) => {
  if (!res.errors) {
    browserHistory.push('/feed/new');
  } else {
    this.setState({ errors: res.errors });
  }
});

【讨论】:

  • 这不起作用。错误在 .catch() 而不是 .then() 上处理
  • 是的,这条评论是在 Apollo 客户端的 API 更改之前发布的。
【解决方案2】:

@stubailo 的先前回答似乎并未涵盖所有用例。如果我在服务器端代码上抛出错误,响应代码将不同于 200,错误将使用.catch() 处理,而不是使用.then()

Link GitHub 上的问题。

最好的办法可能是同时处理.then().catch() 上的错误。

const { deleteProduct } = this.props;
const { selectedProductId } = this.state;

deleteProduct(selectedProductId)
  .then(res => {
      if (!res.errors) {
          // handle success
      } else {
          // handle errors with status code 200
      }
  })
  .catch(e => {
      // GraphQL errors can be extracted here
      if (e.graphQLErrors) {
          // reduce to get message
          _.reduce(
             e.graphQLErrors,
             (res, err) => [...res, error.message],
             []
          );
      }
   })

【讨论】:

  • 想知道为什么没有更优雅的方法来提取错误消息和错误代码。
【解决方案3】:

使用 graphql 标记符号,你可以访问错误:

<Mutation mutation={UPDATE_TODO} key={id}>
        {(updateTodo, { loading, error }) => (
          <div>
            <p>{type}</p>
            <form
              onSubmit={e => {
                e.preventDefault();
                updateTodo({ variables: { id, type: input.value } });

                input.value = "";
              }}
            >
              <input
                ref={node => {
                  input = node;
                }}
              />
              <button type="submit">Update Todo</button>
            </form>
            {loading && <p>Loading...</p>}
            {error && <p>Error :( Please try again</p>}
          </div>
        )}
      </Mutation>

https://www.apollographql.com/docs/react/essentials/mutations.html

【讨论】:

    猜你喜欢
    • 2021-10-06
    • 2021-10-12
    • 2019-06-09
    • 2018-09-03
    • 2018-05-21
    • 2022-11-13
    • 2017-09-06
    • 2019-04-03
    • 2021-09-03
    相关资源
    最近更新 更多