How to handle Kotlin Jetpack Paging 3 exceptions?

Viewed 2241

I am new to kotlin and jetpack, I am requested to handle errors (exceptions) coming from the PagingData, I am not allowed to use Flow, I am only allowed to use LiveData.

This is the Repository:

class GitRepoRepository(private val service: GitRepoApi) {

    fun getListData(): LiveData<PagingData<GitRepo>> {
        return Pager(
            // Configuring how data is loaded by adding additional properties to PagingConfig
            config = PagingConfig(
                pageSize = 20,
                enablePlaceholders = false
            ),
            pagingSourceFactory = {
                // Here we are calling the load function of the paging source which is returning a LoadResult
                GitRepoPagingSource(service)
            }
        ).liveData
    }
}

This is the ViewModel:

class GitRepoViewModel(private val repository: GitRepoRepository) : ViewModel() {

    private val _gitReposList = MutableLiveData<PagingData<GitRepo>>()

    suspend fun getAllGitRepos(): LiveData<PagingData<GitRepo>> {
        val response = repository.getListData().cachedIn(viewModelScope)
        _gitReposList.value = response.value
        return response
    }

}

In the Activity I am doing:

  lifecycleScope.launch {
            gitRepoViewModel.getAllGitRepos().observe(this@PagingActivity, {
                recyclerViewAdapter.submitData(lifecycle, it)
            })
        }

And this is the Resource class which I created to handle exceptions (please provide me a better one if there is)

data class Resource<out T>(val status: Status, val data: T?, val message: String?) {

    companion object {
        fun <T> success(data: T?): Resource<T> {
            return Resource(Status.SUCCESS, data, null)
        }

        fun <T> error(msg: String, data: T?): Resource<T> {
            return Resource(Status.ERROR, data, msg)
        }

        fun <T> loading(data: T?): Resource<T> {
            return Resource(Status.LOADING, data, null)
        }
    }
}

As you can see I am using Coroutines and LiveData. I want to be able to return the exception when it occurs from the Repository or the ViewModel to the Activity in order to display the exception or a message based on the exception in a TextView.

1 Answers

Your GitRepoPagingSource should catch retryable errors and pass them forward to Paging as a LoadResult.Error(exception).

class GitRepoPagingSource(..): PagingSource<..>() {
    ...
    override suspend fun load(..): ... {
        try {
            ... // Logic to load data
        } catch (retryableError: IOException) {
            return LoadResult.Error(retryableError)
        }
    }
}

This gets exposed to the presenter-side of Paging as LoadState, which can be reacted to via LoadStateAdapter, .addLoadStateListener, etc as well as .retry. All of the presenter APIs from Paging expose these methods, such as PagingDataAdapter: https://developer.android.com/reference/kotlin/androidx/paging/PagingDataAdapter

Related