7
votes

is somebody able to explain, why my react app + apollo behaves like this when I try to use mutation which returns error?

enter image description here

GraphQL mutation returns this (response code is 200): {"errors":[{"error":{"result":"identity.not-found","error":"authentication-failed","statusCode":401}}],"data":{"login":null}}

My mutation looks like this:

export const LOGIN_MUTATION = gql`
    mutation($input: LoginInput!) {
        login(input: $input) {
            token
        }
    }
`;

called:

const handleSignIn = () => {
        loginMutation({
            variables: {
                input: {
                    clientId: config.clientId,
                    username: userName,
                    password: password,
                    clientSecret: config.clientSecret
                }
            }
        });
    };

It behaves for awhile like expected (my own custom error component is rendered - {error && <div>error</div>}), but then it throws this unhandled rejection.

If I add catch callback to mutation call, it works as expected.

However, I did not find anywhere in apollo docs any mentions about the need to always catch GraphQL errors such way. This should be sufficient, if I understand it correctly: const [loginMutation, {data, loading, error}] = useMutation(LOGIN_MUTATION);

Is this behaviour correct or do I miss something?

Versions:

"@apollo/react-hooks": "^3.1.3"
"apollo-boost": "^0.4.7"
"graphql": "^14.5.8"
1

1 Answers

3
votes

The mutate function returns a Promise that, by default, will be rejected if your response includes an errors object or if a network error occurs. If you change the errorPolicy to ignore or all, the presence of errors in your response won't cause the Promise to reject, but a network error still will.

The only way to avoid this behavior is to provide an error handler through the onError parameter. If onError is provided, the Promise returned by mutate will always resolve and any relevant errors (depending on your errorPolicy) will be passed to onError instead.

Additional details on error handling in Apollo can be found here. Additional details on unhandled Promise rejections can be found here.