私はこの問題を回避しようと努力してきましたが、それに対する強力な答えは見つかりませんでした。 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によって与えられたエラーの違いは正確に何であり、なぜReactがonErrorのときにエラー画面を表示するのかnot使用。
ありがとう!
ApolloはそのAPIを通じて2種類のエラーを公開します:GraphQLエラー、errors
とともに、data
として応答の一部として返されます、およびリクエストが失敗したときに発生するネットワークエラー。サーバーに到達できない場合、または応答ステータスが200以外の場合、ネットワークエラーが発生します。応答にerrors
が含まれているクエリでも、ステータスが200になる可能性があります。ただし、たとえば無効なクエリは、 400ステータスとApolloクライアントのネットワークエラー。
Apolloクライアントは、実際には変異エラーを処理するための4つの異なる方法を提供します。
1.)フックによって返されたmutate
関数を呼び出すと、Promiseが返されます。リクエストが成功した場合、Promiseはサーバーから返されたdata
を含むレスポンスオブジェクトにresolveします。リクエストが失敗すると、Promiseはエラーでrejectします。これが、コンソールに「未処理の拒否」メッセージが表示される理由です。拒否された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エラーまたはネットワークエラーのいずれかを拒否します。 errorPolicy をignore
またはall
に設定すると、Promiseはネットワークエラーに対してonlyを拒否します。この場合、応答オブジェクトを介してGraphQLエラーにアクセスできますが、Promiseは解決します。
2.)上記の唯一の例外は、onError
関数を指定した場合に発生します。この場合、Promiseは拒否せずに常に解決しますが、エラーが発生した場合、onError
が呼び出され、結果としてエラーが発生します。設定したerrorPolicy
もここに適用されます。onError
は常にネットワークエラーに対して呼び出されますが、errorPolicy
のデフォルトのnone
を使用する場合にのみGraphQLエラーで呼び出されます。 onError
を使用することは、拒否されたPromiseをキャッチすることと同じです。エラーハンドラをmutate
関数の呼び出しサイトからフックの呼び出しサイトに移動するだけです。
3.)mutate
関数に加えて、useMutation
フックは結果オブジェクトも返します。このオブジェクトは、ミューテーションの実行中に発生したエラーも公開します。上記で作成したエラーハンドラー関数とは異なり、このerror
オブジェクトはapplication stateを表します。この方法で公開されたerror
オブジェクトとdata
オブジェクトの両方が、便宜上存在しています。彼らはこれを行うことと同等です:
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)
4.)最後に、 apollo-link-error を使用して、リクエストにglobalエラー処理を追加することもできます。これにより、たとえば、アプリケーションのどこでリクエストが発生したかに関係なく、エラーダイアログを表示できます。
アプリケーションでこれらのメソッドのどれを使用するかは、実行しようとしていることに大きく依存します(グローバルvsローカル、状態vsコールバックなど)。ほとんどのアプリケーションは、エラー処理の複数の方法を利用します。