Query with errorPolicy "all" cannot use onError, onCompleted effectively
See original GitHub issueHi š ! A team of us are working on transitioning a production application to Apollo with use of hooks in React. We have the following use case:
- use a query with errorPolicy set to āallā (so that
error
anddata
may both have value) - use
onError
,onCompleted
attributes to perform some side effects
Intended outcome:
Iād expect to be able to perform ācompletedā and āerroredā functionality if the errorPolicy=āallā, since this would be a congruent outcome of the data, error, loading
pattern commonly used when both data
and error
may be populated with this error policy.
Actual outcome:
If there is a partial error from one of the fields, only onError
called (since Iāve defined both).
I think issue can be found in this either/or method (here in react-apollo, or here in apollographql/apollo-client).
I wonder: could onError
receive data
as a 2nd ordinal argument in the event that there is both an error
and data
?
How to reproduce the issue:
Iāve reproduced here: https://codesandbox.io/s/inspiring-surf-pcrgj?file=/src/App.js
Hereās an inline example:
import {useQuery} from '@apollo/react-hooks`
import gql from 'graphql-tag'
const someSideEffect = (error, data) => {
if (!data) console.error(error)
else if (data && error) {
console.info(error)
alert(`some of the data is shiny: ${data.isShiny}`)
} else {
console.log('no error š')
}
}
const QUERY = gql `
query get_stuff {
stuff {
isShiny
someFinnickyFieldThatErrorsOutSometimes
}
}
`
function Stuff() {
const {data, loading} = useQuery(QUERY, {
errorPolicy: 'all',
onCompleted: (data) => someSideEffect(null, data),
onError: (error) => someSideEffect(error),
});
if (loading) return 'loading...'
if (!loading && data) return <div>{JSON.stringify(data, null, 4)}</div>;
}
Solution Proposal
Possible solution 1: provide data
as a 2nd ordinal argument to onError
const {data, loading} = useQuery(QUERY, {
errorPolicy: 'all',
onCompleted: (data) => someSideEffect(null, data),
// Perhaps It'd be SO nice if onError had access to data ā¤, but it does not š
onError: (error, data) => someSideEffect(error, data),
});
One might also argue additionally (or alternatively) that error in the onCompleted
callback should be made available. Hence, in the case of errorPolicy=āallā this dichotomy between ācompletedā and āerroredā is somewhat difficult to discern. Hence:
Possible Solution 2: Perhaps if developer does not define onError
and errorPolicy
is āallā, then onCompleted
is always called with both data
and error
?
Possible Solution 3: Alternatively, and more generally it should just always call āonCompletedā with access to both error and data when both are defined (errorPolicy=āallā). And we remove the notion of onError entirely?**
In summary, there are many solutions to this perceived bug, and the API seems unclear for this use case. These three solution proposals above are ranked in order from least to most invasive.
Version
@apollo/react-components@3.1.5
System:
OS: macOS Mojave 10.14.6
Binaries:
Node: 12.16.1 - ~/.volta/tools/image/node/12.16.1/6.13.4/bin/node
npm: 6.13.4 - ~/.volta/tools/image/node/12.16.1/6.13.4/bin/npm
Browsers:
Chrome: 83.0.4103.116
Edge: 83.0.478.61
Firefox: 76.0
Safari: 13.0.4
(FYI originally reported here, moving) https://github.com/apollographql/react-apollo/issues/403
Issue Analytics
- State:
- Created 3 years ago
- Reactions:11
- Comments:5
Top GitHub Comments
I am testing with
apollo/client@3.4.1
, I got a completely different result. WhenerrorPolicy=all
, it does not triggeronError
on partial failure.I canāt find the official explanation on the website, when
errorPolicy=all
and when there is a partial error, should it triggeronError
?I found this PR https://github.com/apollographql/apollo-client/issues/6492 and it looks like it was not expected on trigger
onError
.Relevant issue for me in vue-apollo https://github.com/vuejs/vue-apollo/pull/1225/files#r679619257
Iām currently having some troubles when setting
errorPolicy: 'all'
because theonCompleted
callback is being called even ifdata
isnull
. This will result innull
being passed for thedata
argument but the function signature does not reflect this circumstance.Iām using
"@apollo/client": "^3.2.7"
.