web-dev-qa-db-ja.com

Apolloクライアントの変異エラー処理

サーバーでGraphQLとmongooseを使用しています。

検証エラーが発生すると、GraphQLミューテーションはステータスコード200の応答を送信します。クライアント側では、応答は次のようになります。

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

アポロクライアント変異プロミスの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) });
      });

これはどのように行うことができますか?

8
Locco0_0

注:Apolloクライアントの最新バージョンではcatchにミューテーションエラーが表示されるため、この回答(そしておそらく質問全体)は古くなっています。

現在、ミューテーションのGraphQLエラーは、errors内のレスポンスのthenフィールドに表示されます。代わりにcatchに表示する必要があるという主張は確かにあると思いますが、これが 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
stubailo

@stubailoからの以前の回答は、すべてのユースケースをカバーしているようには見えません。サーバー側コードでエラーをスローした場合、応答コードは200とは異なり、エラーは.catch()ではなく.then()を使用して処理されます。

リンク 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
tgdn

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

1
Howl Jenkins