Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo client: How to simply debug a 400 code error?

I'm using Apollo-client and I don't understand why this is so hard to debug my error: I'm trying to perform a mutate call on my graphene python implementation of GraphQL. It end up with a 400 error code, and I have no way to retrieve the info.

For example: when I try my graphene service on the /graphQL interface, it return me helpful errors as bad input or bad methode name. Here, on apollo client, It only throw me a 400 code error. That doesn't help me at all. So is it possible to have the error info from graphene from my apolo client, instead of an unhelpful 400 code error?

Here an example, from my graphene interface (/graphQL):

mutation myMutation {   uploadFile(input:"") {     success   } } 

will output:

{   "errors": [     {       "message": "Argument \"input\" has invalid value \"\".\nExpected \"UploadFileMutationInput\", found not an object.",       "locations": [         {           "column": 20,           "line": 2         }       ]     }   ] } 

When I try the same on apollo client (js):

client.mutate({   mutation: gql`     mutation($file: Upload!) {       uploadFile(input: $file) {         success       }     }   `,   variables: { file } })   .then(console.log)   .catch((e) => { console.log("catch", e) }) 

I get Error: Network error: Response not successful: Received status code 400

My catch is never called, and the documentation is not helping me at all.

What I want is get the mutation detail errors of my calls: When I use improper method call or bad input type, I should not fall in a 400 without any information of what made my request bad.

like image 232
Mr Bonjour Avatar asked Feb 19 '18 09:02

Mr Bonjour


People also ask

How do you handle errors in Apollo GraphQL?

By default, Apollo Client throws away partial data and populates the error. graphQLErrors array of your useQuery call (or whichever hook you're using). You can instead use these partial results by defining an error policy for your operation. If the response includes GraphQL errors, they are returned on error.

What is the status code 400?

The HyperText Transfer Protocol (HTTP) 400 Bad Request response status code indicates that the server cannot or will not process the request due to something that is perceived to be a client error (for example, malformed request syntax, invalid request message framing, or deceptive request routing).

How do I clear the Apollo cache in my browser?

When we have access to the cache object we can call cache. data. delete(key) where key is the key that Apollo is using to store the data for a specific item. And the record will be entirely deleted from the cache.


2 Answers

Error and console.log surprises

When trying to use console.log to view an error, you might be surprised to not see all the error data available. This is because console.log treats values which are instances of the built-in Error class in a special way, printing only the message, the type, and the stack.

Apollo extends its own errors from the built-in Error class. This can be easily tested by:

const error = apolloError // from async try/catch, onError method, or a promise .catch  console.log(error instanceof Error); // --> true 

When extending from Error, Apollo will add it's own data to the object. Yet the error will still be an instance of Error, and thus console.log will only display a limited amount of information,

console.log(error);  // output: // Error: Network error: Response not successful: Received status code 400 //     at ... //     at ... //     at ... 

Suggestion (solution?)

If you know where to look, you can just do a property lookup on the error object. For example, you can log error.networkError.result.errors. This approach may be too surgical and lead to an incomplete picture of all the things that went wrong.

Alternatively, we can use JSON.stringify on the error object, and the entirety of the data will be printed to the console,

// tip: use stringify's formatting options for better readability console.log(JSON.stringify(error, null, 2)); 
{   "graphQLErrors": [],   "networkError": {     "name": "ServerError",     "response": {},     "statusCode": 400,     "result": {       "errors": [...here you will find what you're looking for]     }   },   "message": "Network error: Response not successful: Received status code 400",   "name": "Error",   "stack": "...same as before" } 

and you'll be able to tell at a glance what went wrong.

like image 73
aryzing Avatar answered Sep 27 '22 23:09

aryzing


You should use this link: https://www.npmjs.com/package/apollo-link-error when instantiating ApolloClient. It should go before other links, like so:

import { ApolloClient, ApolloLink } from 'apollo-boost' import { onError } from 'apollo-link-error'  const errorLink = onError(({ graphQLErrors }) => {   if (graphQLErrors) graphQLErrors.map(({ message }) => console.log(message)) })  new ApolloClient({   ...   link: ApolloLink.from([errorLink, authLink, restLink, httpLink]), }) 
like image 21
Yan Takushevich Avatar answered Sep 27 '22 23:09

Yan Takushevich