Error handling


 note
Starting with version 4.0.0, Apollo Kotlin offers a way to handle errors automatically at parsing time. Fields that are nullable only for error purposes can also be generated as non-null in Kotlin. You can read more about it in the "handling nullability" page.

ApolloResponse

ApolloResponse contains three important fields:

  • exception contains the fetch error if any.

  • errors contains the GraphQL errors if any.

  • data contains the returned (potentially partial) data if any.

Use ApolloResponse.data to check if the server returned data:

Kotlin
1if (response.data != null) {
2  // Handle (potentially partial) data
3} else {
4  // Something wrong happened
5  if (response.exception != null) {
6    // Handle fetch errors
7  } else {
8    // Handle GraphQL errors in response.errors
9  }
10}

This is also true when calling toFlow() (e.g. with subscriptions) and watch() (with the normalized cache).

Kotlin
1apolloClient.subscription(subscription).toFlow().collect { response ->
2  if (response.data != null) {
3    // Handle (potentially partial) data
4  } else {
5    if (response.exception != null) {
6      // Handle fetch errors
7    } else {
8      // Handle GraphQL errors in response.errors
9    }
10  }
11}

If you prefer throwing, you can use dataOrThrow() to get a non-null data:

Kotlin
1val data = apolloClient.query(ExampleQuery()).execute().dataOrThrow()
2// data is non-null

Different types of errors

Whenever you execute a GraphQL operation with Apollo Kotlin (or any other GraphQL client), two types of errors can occur:

  • Fetch errors: a GraphQL response wasn't received because an error occurred while communicating with your GraphQL server. This might be an SSL error, a socket error because your app is offline, or a 500 or any other HTTP error. When a fetch error occurs, no data is returned and response.exception is non-null.

  • GraphQL errors: a GraphQL response is received (HTTP 200), and it contains a non-empty errors field. This means the server wasn't able to completely process the query. The response might include partial data if the server was able to process some of the query.

Fetch errors

Fetch errors happen when it's impossible to fetch a GraphQL response. They can have a wide variety of causes (non-exhaustive list):

  • The app is offline or doesn't have access to the network.

  • A DNS error occurred, making it impossible to look up the host.

  • An SSL error occurred (e.g., the server certificate isn't trusted).

  • The connection was closed.

  • The server responded with a non-successful HTTP code.

  • The server didn't respond with valid JSON.

  • The response JSON doesn't satisfy the schema and cannot be parsed.

  • A request was specified as CacheOnly but the data wasn't cached.

  • And more...

You can display an error based on the exception in response.exception

GraphQL errors

GraphQL errors happen when a GraphQL response is successfully fetched but contains GraphQL errors. In that case, the response may contain partial data.

For example, the following query uses an invalid id to look up a Person:

GraphQL
1query FilmAndPersonQuery {
2  film(id: "ZmlsbXM6MQ==") {
3    title
4  }
5  person(id: "badId") {
6    name
7  }
8}

The server will return the following response:

JSON
1{
2  "data": {
3    "film": {
4      "title": "A New Hope"
5    },
6    "person": null
7  },
8  "errors": [
9    {
10      "message": "Cannot find person with id 'badId'",
11      "path": ["person"]
12    }
13  ]
14}

person is null:

Kotlin
1// there was an error fetching data
2println(response.data?.person) // null
3// read the error from response.errors
4println(response.errors?.first()?.message) // "Cannot find person with id 'badId'"
5// partial data is also returned
6println(response.data?.film?.title) //  "A New Hope"
7// exception is null
8println(response.exception) // null

This allows to display as much data as possible without having to do a new network round trip.

Because GraphQL models both errors and semantic nulls as nullable fields, you must check errors to determine whether the field is an error or a true null.

For an example, it is possible for a person to not have a starship:

JSON
1{
2  "data": {
3    "person": {
4      "starship": null
5    }
6  }
7}

In that case, starship is a true null and not an error.

Truth table

exceptiondataerrorsmeaning
nullnullnullNon-compliant server, if data is null, there should be at least one error
nullnullpresentA GraphQL request error happened or a Graph field error bubbled up.
nullpresentnullComplete data was received.
nullpresentpresentPartial data was received alongside field error(s).
presentnullnullA fetch error happened.
presentnullpresent🙅‍♂️ impossible.
presentpresentnull🙅‍♂️ impossible.
presentpresentpresent🙅‍♂️ impossible.
Feedback

Edit on GitHub

Forums