react-apollo useMutationフックによるエラーの処理


10

私はこの問題を回避しようと努力してきましたが、それに対する強力な答えは見つかりませんでした。useMutationフックを使用してログインミューテーションを実行しようとしています。

TLDR; オプションで渡されたonErrorとuseMutationによって私に与えられたエラーの違いは何ですか?

これが私のコードスニペットです

const [login, { data, loading, error }] = useMutation(LOGIN_QUERY, {
        variables: {
            email,
            password
        },
        onError(err) {
            console.log(err);
        },
});

サーバー側では、ログインに使用するプリセット/ハードコードされたメールを使用していますが、Apolloや他のクライアントを使用していません。このログイン変異のリゾルバーでは、メールが同じでない場合はエラーをスローします

throw new Error('Invalid Email');

クライアント側(React)でこのエラーを処理したいと思います。しかし、私の懸念は、useMutationフックから返された「エラー」を使用し、この方法でエラーを表示しようとすると、

render() {
...
{error && <div> Error occured </div>}
...
}

エラーはUIで更新されますが、すぐにReactに未処理の拒否(エラー)の画面が表示されます。Graphqlエラー:My-custom-error-message

しかし、useMutate関数にオプションで渡されたonErrorを使用すると、この画面は表示されず、エラーに対して何でも実行できます。

オプションで渡されたonErrorとuseMutationによって与えられたエラーの違いは何なのか、そしてonErrorが使用されていないときにReactがエラー画面を表示する理由を知りたいのですが。

ありがとう!

回答:


32

:アポロは、そのAPIを使用してエラーの2種類公開しGraphQLエラーとして応答の一部として返され、errors一緒に、data、およびネットワークエラー要求が失敗したときに発生します。サーバーに到達できない場合、または応答ステータスが200以外の場合、ネットワークエラーが発生します。応答に含まれるクエリerrorsは、ステータスが200のままになる可能性があります。ただし、無効なクエリなどは、 Apolloクライアントの400ステータスとネットワークエラー。

Apolloクライアントは、実際には変異エラーを処理するための4つの異なる方法を提供します。

1.)mutateフックによって返された関数を呼び出すと、Promiseが返されます。リクエストが成功すると、Promiseはサーバーから返されたものを含むレスポンスオブジェクトに解決dataます。リクエストが失敗した場合、Promiseはエラーで拒否します。これが、コンソールに「未処理の拒否」メッセージが表示される理由です。拒否されたPromiseを処理する必要があります。

login()
  .then(({ data }) => {
    // you can do something with the response here
  })
  .catch(e => {
    // you can do something with the error here
  })

またはasync / await構文:

try {
  const { data } = await login()
} catch (e) {
  // do something with the error here
}

デフォルトでは、PromiseはGraphQLエラーまたはネットワークエラーのいずれかを拒否します。ただし、errorPolicyignoreまたはに設定するallと、Promiseはネットワークエラーに対してのみ拒否します。この場合、応答オブジェクトを介してGraphQLエラーにアクセスできますが、Promiseは解決します。

2.)上記の唯一の例外は、onError関数を提供する場合です。この場合、Promiseは常に拒否するのではなく解決しますが、エラーが発生した場合はonError、結果のエラーで呼び出されます。errorPolicy-あなたが設定はここにも適用されonError、常にネットワークエラーのために呼び出されますが、デフォルト使用している場合にのみGraphQLエラーで呼び出されるerrorPolicyのをnone。を使用することonErrorは、拒否されたPromiseをキャッチすることと同じです。エラーハンドラをmutate関数の呼び出しサイトからフックの呼び出しサイトに移動するだけです。

3.)mutate関数に加えて、useMutationフックは結果オブジェクトも返します。このオブジェクトは、ミューテーションの実行中に発生したエラーも公開します。上記で作成したエラーハンドラー関数とは異なり、このerrorオブジェクトはアプリケーションの状態を表します。この方法で公開されたオブジェクトerrordataオブジェクトの両方が、便宜上存在しています。それらはこれを行うことと同等です:

const [mutate] = useMutation(YOUR_MUTATION)
const [data, setData] = useState()
const [error, setError] = useState()
const handleClick = async () => {
  try {
    const { data } = await mutate()
    setData(data)
  catch (e) {
    setError(e)
  }
}

このようなエラー状態は、UIにエラーがあるという事実を反映させたい場合に役立ちます。たとえば、突然変異がエラーなしで実行されるまで、要素の色を変更できます。上記のボイラープレートを自分で作成する代わりに、提供された結果オブジェクトを使用できます。

const [mutate, { data, error }] = useMutation(YOUR_MUTATION)

注:公開されたエラー状態を使用してUIを更新できますが、実際にエラーを処理する代わりにはなりません。未処理のPromise拒否に関する警告を回避するには、コールバックまたはエラーを提供する必要あります。onErrorcatch

4.)最後に、apollo-link-errorを使用して、リクエストにグローバルエラー処理を追加することもできます。これにより、たとえば、アプリケーションのどこでリクエストが発生したかに関係なく、エラーダイアログを表示できます。

アプリケーションでこれらのメソッドのどれを使用するかは、実行しようとしていることに大きく依存します(グローバルvsローカル、状態vsコールバックなど)。ほとんどのアプリケーションは、エラー処理の複数の方法を利用します。


説明ありがとう !賛成投票!
HyphæneOhmen
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.