apollo-client: ApolloClient onError doesn't catch mutation errors anymore
Here is my client configuration using Apollo Boost :
new ApolloClient({
uri: `${window.location.origin}/api`,
cache: new InMemoryCache(),
onError({ graphQLErrors, networkError }) {
if(graphQLErrors)
graphQLErrors.forEach(error => notification.error({
message: 'Error',
description: error.message
}))
if(networkError)
notification.error({
message: 'Network Error',
description: `A network error has occurred. Please check out your connection.`
})
},
request(operation) {
const currentUser = readStore('currentUser')
currentUser && operation.setContext({
headers: { authorization: currentUser.token }
})
}
})
Intended outcome: Before the bug, the onError callback used to catch errors just fine.
Actual outcome: Errors are said to remain uncaught and cause apps (using CRA in my case) to crash.
How to reproduce the issue: Try switching to the latest version of apollo-boost and just throw a Graphql error on the server.
Versions React : 16.12.0 Apollo-boost : 0.4.7
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 47
- Comments: 48 (7 by maintainers)
Commits related to this issue
- Swallow re-thrown mutation errors apollographql/apollo-client#5708 — committed to koverto/koverto-web by jbhannah 4 years ago
- Working to catch errors Apollo doesn't solve the onError crash: https://github.com/apollographql/apollo-client/issues/5708 — committed to albertcito/react-graphql-urql by deleted user 4 years ago
- add onError callback to catch unhandled error excecption bug https://github.com/apollographql/apollo-client/issues/5708 — committed to FitFam/www by swolidity 3 years ago
Any update on this? I have a pretty large app that relied on this pattern to minimize the amount of try/catch and .catch that was needed. Made for a super clean code base knowing I could rely on apollo-link-error when needed.
Not sure what changed, guess I need to look at my past few commits, but lately all mutation errors throw an unhandled error.
Is this change documented in a change log somewhere?
Any updates on this one? I can’t believe this issue still not addressed yet
Why is there no activity on this issue? It has been around since December 2019,
useQuery
anduseLazyQuery
work as expected so it seems like a deal-breaker for me. I don’t want to write try/catch logic around mutations, that’s why I use the hooks so I can respond to changes in the UI without side-effect code.But…,finally, I resolved by adding
catch
in promise mutation, for example. You have:const [login] = useMutation(LOGIN)
then when you call mutation by an event
Our issue may resolve, but
onError
issue is still there, maybe because of promising stream is not correctly, I’m not sure.Hello! Apollo staff here. First of all I want to apologize for the lack of response in this 43 comment, 3 year old issue. I’m sorry that you all had to experience being here. However, I am also glad to see people using this issue as a way to help each other. For instance, I personally appreciate comments likes those of @valentingavran https://github.com/apollographql/apollo-client/issues/5708#issuecomment-824727128, @viiiprock https://github.com/apollographql/apollo-client/issues/5708#issuecomment-569268951 and @Illia-Linevych https://github.com/apollographql/apollo-client/issues/5708#issuecomment-825201861, people who went out of their way to try and help others even after they had solved their own problems. I also appreciate the comment from @kissthom https://github.com/apollographql/apollo-client/issues/5708#issuecomment-588300148 attempting to find the source of the error in what is likely now a very outdated version of the codebase. I can’t respond directly to every comment in this issue, because that would take a lot of time, but I’m glad that this has been a place for people to help each other, even if we are all frustrated when we’re here.
The problem, as best I understand it, is that the
useMutation()
hook, in earlier versions of Apollo Client, threw unhandled errors or promise rejections, and that this was causing problems for developers, especially those who use tools likereact-dev-server
, because the developers who created those tools, thought it would be a good developer experience to throw up an overlay any time it detected an error. Spoiler alert, it’s not.One thing that complicates this issue is that there are different kinds of errors that can be thrown. Network errors, and errors passed to the client from the server, for instance, might bubble up from the link abstraction, which is why people have suggested overriding the flexible link abstraction to ignore the network error.
Other solutions, like adding an
onError()
callback to theuseMutation()
hook, have been added in successive versions of Apollo Client, and they can also squash the error. Additionally, theuseMutation()
execute()
function returns a promise, which if not caught, could, in various versions, cause unhandled promise rejections.In my estimation, I think people in this issue could be talking about any of these sources or mitigations errors. All of these issues have hopefully been remedied in the latest version of Apollo Client (^3.6), and we encourage you to update when you get the chance.
In short, I think the problems in this issue have been addressed by the latest version of Apollo Client, and I encourage you to open new issues, and hopefully issues with code snippets, if you think we have not addressed the problems in this issue.
If you’re just looking for a place to vent about Apollo and GraphQL, I hear you. I feel the same way about a lot of this. Please do not let me closing this issue prevent you from complaining. Go right ahead. Nevertheless, we hope to surprise and delight you with what we got in store for y‘all. 😊 Thank you for engaging with us!
I’m having a similar issue. When the response from a mutation contains an error I get an error that there was an unhandled rejection. This slows development since
react-dev-server
displays an error overlay that you have to close. Errors fromuseQuery
anduseLazyQuery
are handled differently, they get caught internally byapollo-client
. At the moment I’m doingbut that’s not ideal either. I was previously using apollo-boost and this was not an issue.
Found a workaround that worked for me in an old issue comment.
With apollo-link-error
return Observable.of(operation);
at the end of the error handling logic.Also experiencing this issue (onError not invoked for mutation errors) on @apollo/client v3.3.14
for me query errors are fine and mutation errors throw uncaught exception, can you confirm if you have the same problem?
To be clear, we believe the original
onError
regression should have been addressed by PR #9076, which was first released in v3.5.4. This issue probably should have been closed when that PR was released, so at least we could’ve found out sooner if it wasn’t really fixed. We are (as @brainkim said) happy to continue the discussion here and reopen if necessary!I think it’s going in the right direction @adisrael , but it’s not working for me.
I mean, I see the global log
console.log([GraphQL error]...
, but shouldn’t it go back also until the mutation? and have result.errors filled?Thx for your help
also seeing the same problem. @viiiprock thanks for the workaround.
is this considered a bug or an expected behavior? can someone from the apollo team chime in here?
it’s been 2.5 years, and afaict, no one from the apollo team has chimed in.
Maybe it’s time to move away from apollo? 🤔
Was able to find a hack/solution by overriding the default value of errorPolicy specifically for mutations.
Noticed that the line of code that’s throwing these errors occurs at https://github.com/apollographql/apollo-client/blob/v3.5.8/src/core/QueryManager.ts#L238.
So you can simply just set the
errorPolicy
to a non'none'
value (I opted for'all'
) at the client level with defaultOptions. This way you don’t have totry/catch
or use.mutation().catch()
after each usage since it no longer throws an error, just returns theerror
result.e.g:
The difference of using
'all'
rather than the default'none'
wasn’t problematic since the codebase I work with never relied ondata
to beundefined
, and instead relied on the existence of anerror
response.I’m try to fix it with response.errors = undefined but it doesn’t work in any case. I have to add the
onError
in each query or mutation 😕Same issue here.
If I had to guess I’d say this line in the catch block makes the trouble.
MutationData.runMutation
Of course I don’t know the whole implementation but it seems to me that in MutationData.onMutationError the errors are already handled pretty well, onError will be called conditionally as it should be so I’m not sure if rethrowing the error is really necessary.
Another workaround is to provide a custom
fetch
function which transforms the HTTP response code to a200
:I eventually moved to urql. No regrets.
I’m not sure if I understood this issue correctly, but according to the information I found in the documentation, here’s how you should catch the errors. This works for me without any problems. Maybe this will help someone.
It’s a big Apollo’s fail. Looks like the library has some problem. It has more than 600 open issues and the roadmap for the V3 is from 2018. I don’t know if it will be done. About the onError I “fixed” it with a patch:
So you can use it like. I’m using codegen:
hate this lib and react. bloated and fully opinionated 👎
apollo v3.1.3 confirm the same error
@ryanrhee I am chiming right now let me just read through 40 comments of people talking past each other, one sec.
I tried this, but this way the
onError
handler is never calledAny update regarding this issue?
the only workaround that seems to work for me is to provide
onError: () => null
as described aboveconfused about how the many apollo-client users work around this? only using
onError
/onCompleted
callbacks? wrapping all mutation promises withtry { ... } catch (err) { ... }
?Still broken. Used code similar to example from docs:
Setting error policy does not work.
The only working way I found is to use
catch
afterclient.query()
:But catching errors like this (especially if you’re working on a big project) is definitely the way to an asylum.
Hi there. Pinging this thread because I believe I’m running into this issue as well. I’m getting
networkError
when a mutation errors. Could anyone provide a working alternative, or could Apollo advise us on how we should proceed? Thanks.Using
return Observable.of(operation)
results onMissing field 'XXX' while writing result {}
error being printed on console, any idea how to solve this?@krakzk Yep, for sure!
On my end, the “custom error catching logic” do operations depending on extension categories / content of messages, then dispatch an action to my errors reducer. Hope it helps.