Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL - How to respond with different status code?

Tags:

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?

like image 958
slorenzo Avatar asked Mar 21 '17 20:03

slorenzo


People also ask

Does GraphQL use HTTP status codes?

By default, when you throw a GraphQLException , the HTTP status code will be 500. If your exception code is in the 4xx - 5xx range, the exception code will be used as an HTTP status code. throw new GraphQLException("Not found", 404); GraphQL allows to have several errors for one request.

How do you send responses in GraphQL?

GraphQL requests can be sent via HTTP POST or HTTP GET requests. GET requests must be sent in the following format. The query, variables, and operation are sent as URL-encoded query parameters in the URL. In either request method (POST or GET), only query is required.

Which status code does GraphQL use to handle errors?

If a GraphQL error prevents Apollo Server from executing your operation at all, it responds with a 4xx status code.

Can GraphQL have multiple schemas?

The idea is to define several GraphQL schemas, and tell the server which one to use on runtime, based on the requested endpoint. When using a JavaScript server, a convenient way to achieve this is with GraphQL Helix, which decouples the handling of the HTTP request from the GraphQL server.


2 Answers

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 }),
}));
like image 164
helfer Avatar answered Oct 24 '22 07:10

helfer


There has been a recent addition to the spec concerning errors outputs:

GraphQL services may provide an additional entry to errors with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to add additional information to errors however they see fit, and there are no additional restrictions on its contents.

Now using the extensions field you can custom machine-readable information to your errors entries:

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [ { "line": 6, "column": 7 } ],
      "path": [ "hero", "heroFriends", 1, "name" ],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

Latest version of Apollo-Server is spec-compliant with this feature check it out, Error Handling.

like image 38
Glenn Sonna Avatar answered Oct 24 '22 05:10

Glenn Sonna