Having deferred store the exception

The easy way to handle the exception is by waiting on the deferred using join() instead of await(). This way, the exception will not be propagated when waiting. The updated code looks like this:

private fun asyncLoadNews() = launch {
val requests = mutableListOf<Deferred<List<String>>>()

feeds.mapTo(requests) {
asyncFetchHeadlines(it, dispatcher)
}

requests.forEach {
it.join()
}
...
}

Now if you run the application, you will see that it still crashes. This is happening because even though we are not propagating the exception when waiting for deferred, we are propagating the exception when reading from it. Calling getCompleted() in a deferred that was cancelled—in this case because of an exception—will throw the exception.

So we need to also update the code so that getCompleted() is called only when deferred didn't fail:

val headlines = requests
.filter { !it.isCancelled }
.flatMap { it.getCompleted() }
At the time of writing, there is an effort from the Kotlin team to make the code above work as expected here. If you notice that the list of headlines is not being loaded correctly, please replace isCancelled with isCompletedExceptionally. I decided to avoid explaining isCompletedExceptionally because it's being deprecated close to the release of the book. For more information, please read issue 220 in the coroutines' Github repository.

Now, running the application will not crash when an invalid feed is added to the list. It will also handle the device not having connectivity without crashing:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.140.196.244