Error handling

There are several types of errors that can happen when calling the API:

  1. Problems (5xx HTTP codes, 1xxx WebSocket codes).

  2. Client problems e.g., rate-limited, unauthorized, etc. (4xx HTTP codes.

  3. The query is missing/malformed.

  4. The query fails GraphQL internal validation (syntax, schema logic, etc.).

  5. The user-supplied variables or context is bad and the resolve/subscribe function intentionally throws an error (e.g. not allowed to view requested user).

  6. An uncaught developer error occurred inside the resolve/subscribe function (e.g., poorly written database query).

  7. The query has exceeded the maximum number of cost units per query.

For errors 1-3 above, the application gets an HTTP error, so the response won't be a GraphQL response because the error happened before running the GraphQL server.

For error 4, the request is received by the server but fails in the very first step and the response only has the error node:

{
"errors": [
    {
      "message": "Some error message",
      "locations": [
        {
          "line": 16,
          "column": 9
        }
      ]
    }
}

For errors 5 and 6, the response has a HTTP 200 code and the response shows a mixed data and errors nodes. This is because the API tries to resolve the query as much as possible and returns errors when something goes wrong.

{
  "data": {
    "feedback": {
      "pageInfo": {
        "endCursor": "9w788rXX==",
        "hasNextPage": true
      },
      "totalCount": 136037,
      "nodes": [
        {
          "e_responsedate": {
            "values": [
              "2018-05-02 10:35:18"
            ]
          },
          "lalala": null #when an error happens, the data is null
          },
          "unit": {
            "units": [
              {
                "name": "(I) *** Unit Pending"
              }
            ]
          }
        }
      ]
    }
  },
  "errors": [
    {
      "message": "Exception while fetching data (/responses/nodes[0]/e_responsedate) : Invalid field ids: [lalala]",
      "locations": [
        {
          "line": 16,
          "column": 9
        }
      ]
    },

  "_links": null,
  "_allowed": [
    "GET"
  ]
}

For error 7, the response has a HTTP 200 code and the response shows the current query cost and the cost-unit limit per query. For information about query cost, see Restrictions and limits.

{
  "data": null,
  "errors": [
    {
      "message": "Maximum query cost exceeded: 245000000 > 3000000",
      "locations": []
    },

  "_links": null,
  "_allowed": [
    "GET"
  ]
}

When a response has no error, the response is warrantied. But when there is an error, the API performs a best-effort to retrieve the data.

It is possible to get a partial response when there is more that one root node in the query. When a root node fails, the result it null for that node; but other nodes may return results. Consider this example, if responses fails, its result is null, but if fields succeeds, its response has the proper results.

query{
    responses{ … },
    fields{ … }
}