You're viewing documentation for a version of this software that is in development. Switch to the latest stable version
/
Launch Apollo Studio

Errors


GraphQL has fine control for error handling. When executing a GraphQL operation, errors can be of two kinds:

  • Transport errors: a GraphQL response wasn't received because a transport error happened. This can be a SSL error, a socket error because your app is offline or a 500 or any other HTTP error. In this case you will not get any data.
  • GraphQL errors: a GraphQL response containing errors is received. This means the server wasn't able to completely process the query. You may get partial data if the server was able to process part of it.

Transport errors

Transport errors throw an ApolloException. To handle them, wrap your query in a try/catch block:

try {
  val response = apolloClient.query(query)
} catch(exception: ApolloException) {
  // handle exception here
}

Transport errors typically happen in these cases (non-limitative):

  • The app is offline or doesn't have access to the network
  • A DNS error happened, impossible to lookup the host
  • A SSL error happened, the server certificate isn't trusted or something else
  • The connection was closed
  • Any non-successful HTTP error code
  • The server did not send a valid json
  • The response json doesn't satisy the schema and cannot be parsed
  • A request was specified as CacheOnly but the data wasn't cached

Examine the exception to get more detailed information about the actual error happening.

GraphQL errors

Because GraphQL errors might still contain data, they do not throw but will instead return a Response with a Response.errors field indicating were the errors happened.

For an example, the below query uses a wrong id to lookup a person:

query FilmAndPersonQuery {
  film(id: "ZmlsbXM6MQ==") {
    title
  }
  person(id: "badId") {
    name
  }
}

The server will send the following response:

{
  "data": {
    "film": {
      "title": "A New Hope"
    },
    "person": null
  },
  "errors": [
    {
      "message": "No entry in local cache for https://swapi.dev/api/people/m�H/",
      "locations": [
        {
          "line": 35,
          "column": 3
        }
      ],
      "path": [
        "person"
      ]
    }
  ]
}

Note that while there are errors, the query successfully returned the title of the film: "A New Hope". In general, any error while executing an operation will bubble up to the next nullable field. Here person is nullable. In the worst case, response.data can be null if everything else is non-nullable.

Apollo Android gives you access to both the data and the errors in the Response class:

val response = try {
  apolloClient.query(query)
} catch(exception: ApolloException) {
  // transport error, not much to do
  throw exception
}

// It's possible to display the film title
val title = response.data?.film?.title
if (title != null) {
  println(title)
}

// The person triggered an error
val person = response.data?.person?.name
if (person != null) {
  // do something with response.errors
}

If you don't want to handle partial responses you can use dataOrThrow() that will return a non-nullable data and throw if there are any errors:

val data = try {
  apolloClient.query(query).dataOrThrow
} catch(exception: ApolloException) {
  // All transport or GraphQL errors are handled here
  throw exception
}

// No need for safe calls on data
val title = data.film?.title

Note that the safe call is still required on film because this field has a nullable type in the GraphQL schema. There are ways to override this in the codegen. See @nonnull for more details.

Edit on GitHub