Apollo client mutation error handling

不打扰是莪最后的温柔 提交于 2019-12-01 00:58:00

问题


I'm using GraphQL and mongoose on the server.

When a validation error occurs the GraphQL mutation sends a response with status code 200. On the client side the response looks like this:

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

I would like to get access to the validation error using the catch functionality of the apollo-client mutation promise. Something like:

      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) });
      });

How can this be done?


回答1:


Note: This answer (and arguably the whole question) is now outdated, since mutation errors show up in catch in more recent versions of Apollo Client.

GraphQL errors from the mutation currently show up in the errors field on the response inside then. I think there's definitely a claim to be made that they should show up in the catch instead, but here's a snippet of a mutation from GitHunt:

// 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 });
  }
});



回答2:


The previous answer from @stubailo does not seem to cover all use cases. If I throw an error on my server side code the response code will be different than 200 and the error will be handled using .catch() and not using .then().

Link to the issue on GitHub.

The best is probably to handle the error on both .then() and .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:


Using graphql tag notation, yo have access to errors:

<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



来源:https://stackoverflow.com/questions/43471623/apollo-client-mutation-error-handling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!