apollo-link-rest
apollo-link-rest copied to clipboard
Feature: Consistent Backend Error Responses should have a way to parse them?
I am integrating apollo-link-rest in a react native app but if I do not disable the cache I always get this error:
Error: Error writing result to store for query: {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"register"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"RegistrationDetails"}}},"directives":[]}],"directives":[],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"register"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"directives":[{"kind":"Directive","name":{"kind":"Name","value":"rest"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"type"},"value":{"kind":"StringValue","value":"NoResponse","block":false}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"StringValue","value":"User/register","block":false}},{"kind":"Argument","name":{"kind":"Name","value":"method"},"value":{"kind":"StringValue","value":"POST","block":false}}]}]}]}}],"loc":{"start":0,"end":156}} Cannot read property 'register' of undefined
Here my mutation
export const REGISTER_USER = gql
mutation register($input: RegistrationDetails!) { register(input: $input) @rest(type: "NoResponse", path: "User/register", method: "POST") }
;
And also how I create link and client
const restLink = new RestLink({ uri: 'http://10.0.2.2:5001/api/', });
const client = new ApolloClient({ link: restLink, cache: new InMemoryCache(), });
I have tried to use cross-fetch but the outcome is the same, the only way is to disable the cache.
After some tests:
My REST endpoint return 200 with the response (either object or array) for the happy path. When there is something wrong with the request they return 400 and an object with a property called errors
When 400 is met (example: user trying to register with an unsafe password) apollo tries to save the response into the cache expecting an object like this
{data: { register: {} }, errors: {...} }
Since the actual response is
{errors: [{password: "Invalid password}]
it fails when it tries to access the 'register' property
My solution for now is to pass fetchPolicy: 'no-cache'
and update the cache (when needed, manually) after the request when it succeeds
If you want to add a feature to handle error responses somehow I'd be happy to discuss it further.
I am facing the same issue for this one. I have a mutation that calls to my BE API which will validate and respond. This is my BE response:
422:
{
errors: {
overlap: ["availability_overlapped"]
},
success: false
}
This response caused my mobile app to crash and show the same error as this issue.
I tried other error responses without the errors
key and all went well.
400: {
success: false
}
When I see the log, I notice that the errors
were populated into GraphQL errors
. I don't know this is an intentional or a bug so I comment here to ask. Here is my log
To reconfirm the fetchPolicy: 'no-cache'
is one way to bypass it 👍. I cannot change the errors
key from BE into another name to check deeper due to my BE convention.
My library versions:
"apollo-client": "^2.6.4",
"apollo-link": "^1.2.13",
"apollo-link-context": "^1.0.19",
"apollo-link-error": "^1.1.12",
"apollo-link-http": "^1.5.16",
"apollo-link-rest": "^0.7.3",
GraphQL errors
is how ApolloClient propagates errors upwards. Glad you have a workaround re: fetch-policy
ApolloClient has changed significantly in 3.x, and apollo-link-rest's version v0.8.0 is the current version of the project that's compatible with that.
If you can replicate this in v0.8.0 @huylocit14054 then we can investigate this further.