apollographql / apollo-link-rest

Use existing REST endpoints with GraphQL
MIT License
789 stars 122 forks source link

Feature: Consistent Backend Error Responses should have a way to parse them? #250

Open nicecatch opened 4 years ago

nicecatch commented 4 years ago

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.

nicecatch commented 4 years ago

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

fbartho commented 4 years ago

If you want to add a feature to handle error responses somehow I'd be happy to discuss it further.

huylocit14054 commented 2 years ago

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

Screen Shot 2021-12-29 at 10 34 41

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",
fbartho commented 2 years ago

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.