GraphQL - How to respond with different status code?

slorenzo picture slorenzo · Mar 21, 2017 · Viewed 16.9k times · Source

I'm having a trouble with Graphql and Apollo Client.

I always created different responses like 401 code when using REST but here I don't know how to do a similar behavior.

When I get the response, I want it to go to the catch function. An example of my front-end code:

client.query({
  query: gql`
    query TodoApp {
      todos {
        id
        text
        completed
      }
    }
  `,
})
  .then(data => console.log(data))
  .catch(error => console.error(error));

Can anybody help me?

Answer

helfer picture helfer · Mar 22, 2017

The way to return errors in GraphQL (at least in graphql-js) is to throw errors inside the resolve functions. Because HTTP status codes are specific to the HTTP transport and GraphQL doesn't care about the transport, there's no way for you to set the status code there. What you can do instead is throw a specific error inside your resolve function:

age: (person, args) => {
  try {
    return fetchAge(person.id);
  } catch (e) {
    throw new Error("Could not connect to age service");
  }
}

GraphQL errors get sent to the client in the response like so:

{
  "data": {
    "name": "John",
    "age": null
  },
  "errors": [
    { "message": "Could not connect to age service" }
  ]
}

If the message is not enough information, you could create a special error class for your GraphQL server which includes a status code. To make sure that status code gets included in your response, you'll have to specify the formatError function when creating the middleware:

app.use('/graphql', bodyParser.json(), graphqlExpress({ 
    schema: myGraphQLSchema,
    formatError: (err) => ({ message: err.message, status: err.status }),
}));