I am using apollo server and apollo client. Here is a resolver passed to apollo server:
loginUser: async (root, { email, password }) => {
const users = await User.filter({ email });
if (isEmpty(users)) {
throw new Error('No user with that email address exists.');
}
const user = head(users);
console.log(await user.validatePassword(password));
if (!await user.validatePassword(password)) {
throw new Error('Invalid email or password.');
}
const authToken = user.signJwt();
return { user, authToken };
}
and my query
client.query({
query: gql`
query User($email: Email!, $password: Password!) {
loginUser(email: $email, password: $password) {
user {
id
email
}
authToken
}
}
`,
variables: {
email: email.value,
password: password.value
}
}).then((result) => {
console.log('got result: ', result);
}).catch((error) => {
console.log('there was an error sending the query: ', error);
});
Everything works correctly, however when the resolve method throws an Error, the client console prints QueryManager.js:409 Uncaught (in promise) ApolloError {graphQLErrors: Array[1], networkError: undefined, message: "GraphQL error: No user with that email address exists."}.
What am I doing wrong? The .catch method catches the error and logs it, but I am also receiving this uncaught (in promise) error. How can I avoid this?
Good catch! I think just one small change would fix this. We shouldn't call reject here, since we already dispatched an error action: https://github.com/apollostack/apollo-client/blob/378cbbe6054d0bae2b4ede2387d19dc2d1927567/src/QueryManager.ts#L732
We already identify unhandled errors here: https://github.com/apollostack/apollo-client/blob/378cbbe6054d0bae2b4ede2387d19dc2d1927567/src/QueryManager.ts#L294
Please submit a PR for this, or otherwise we will try to get to it ASAP.
Should be fixed with #445. If it isn't, we can re-open the issue.
Released in 0.4.8!
@octohedron Please open a new issue with an accurate description of the error you're experiencing.
I am still seeing this bug. Is this not fixed in the latest ApolloClient?
OK, a tentative work around is the following:
handleFormSubmit = ({variables, mutation}) => {
// The catch below prevents the unhandled promise rejection ...
mutation({variables}).catch(error => console.log("An error", error));
}
...
<Mutation ...>
{mutation => <SomeForm onSubmit={variables => handleFormSubmit({variables, mutation})}/>}
</Mutation>
I wanted to share this to help others.
However, this is a violation of the principle of least surprise - if I'm already handling the error in the Mutation child function or its onError property callback, I shouldn't also need to handle it when invoking the mutation. This is very confusing and should be fixed by the Apollo team - it looks like you're still double-rejecting the promise?
Also ran into this bug when returning unauthorized response (with React Native). Followed suite and not adding a catch() on our mutations to handle this promise.
Would love to just have our error component deal with this instead.
Most helpful comment
OK, a tentative work around is the following:
I wanted to share this to help others.
However, this is a violation of the principle of least surprise - if I'm already handling the error in the
Mutationchild function or itsonErrorproperty callback, I shouldn't also need to handle it when invoking the mutation. This is very confusing and should be fixed by the Apollo team - it looks like you're still double-rejecting the promise?