2

This code - manual query execution without watch - throws an exception as I expect it (due to an intentionally wrong server url not shown here):

try {
    val response = apolloClient.query(MyQuery()).execute()
} catch (e: Exception) {
    Timber.e("exception from manual execution")
    Timber.e(e)
}

However, if instead I use watch (and intentionally the same wrong server url) like in the following code, I get no exception:

try {
    apolloClient.query(MyQuery())
        .watch() // flow
        .collect { response ->
            Timber.i("apollo watch collect called")
        }
} catch (e: Exception) {
    Timber.e("exception from watch execution")
    Timber.e(e)
}

Where is my error? Why don't I get an exception in the second case? How to catch errors when using watch?

stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270

3 Answers3

1
apolloClient.query(MyQuery())
        .watch( fetchThrows = true, refetchThrows = true) // need this
        .catch{t->}//catch here
        .collect { response ->
            Timber.i("apollo watch collect called")
        }
stefan.at.kotlin
  • 15,347
  • 38
  • 147
  • 270
Shift Delete
  • 1,015
  • 6
  • 13
  • 1
    thank you, that worked fine and looks the most intuitive to me :-) it needs to be combined with `.watch( fetchThrows = true, refetchThrows = true)` though. – stefan.at.kotlin Apr 05 '23 at 10:59
0

use a callback on the ApolloQueryWatcher instance. Here is an example from GitHub

Also use .responseFetcher(ApolloResponseFetchers.CACHE_ONLY) with any enqueueAndWatch calls to make sure that watchers won't perform any network requests when the cache is updated and prevent Infinite loops

RAI
  • 584
  • 9
0

The collect function starts the flow and consumes the emitted values, but it does not throw any exceptions.

Use the onCompletion operator to handle any errors that occur during the execution of the flow.

apolloClient.query(MyQuery())
    .watch()
    .onCompletion { throwable ->
        if (throwable != null) {
            Timber.e("error from watch execution")
            Timber.e(throwable)
        }
    }
    .collect { response ->
        Timber.i("apollo watch collect called")
    }

A slight improvement: if the emitted values are being ignored it is possible to just use
.launchIn(scope) instead of .collect { response -> ...

diziaq
  • 6,881
  • 16
  • 54
  • 96