Где правильнее обработать ошибку получения данных?
Используя retrofit я получаю данные и сохраняю их в Room, после чего я уже работаю с данными из кэша в своем приложении.
Данные я загружаю при создании viewModel и по расписанию используя Worker. И у меня проблема с обработкой ошибок, например httpException.
Если я добавляю try{} catch(e: HttpException) в метод loadModels() моего репозитория, то тогда я начинаю их перехватывать везде и возвращение Result.retry() теряет смысл.
Но я бы хотел так же обрабатывать ошибки и в моем ModelWorker, как это я делаю сейчас. Где мне правильнее обрабатывать ошибки получения данных?
Только в моём репозитории или не обрабатывать там вовсе? Ведь тогда я рискую получить ошибку при создании viewModel.
Упрощенный пример кода:
interface ModelApi {
suspend fun loadModels(): List<Model>
}
class ModelRepository(service: ModelApi) {
suspend fun refreshModels() : List<Model>{
saveRoom(service.loadModels())
}
}
class ModelWorker(private val repository: ModelRepository) : CoroutineWorker() {
override suspend fun doWork(): Result {
try {
repository.refreshModels()
} catch (e: HttpException) {
return Result.retry()
}
return Result.success()
}
}
class ModelViewModel() : ViewModel() {
private val repository = ModelRepository()
init {
viewModelScope.launch {
repository.refreshModels()
}
}
}
Ответы (1 шт):
Можно создать класс-обертку на подобии этой:
sealed class Response<out T> {
data class Success<T>(val data: T) : Response<T>()
data class Exception(val error: Exception) : Response<Nothing>()}
Далее, обрабатывать ошибки в репозитории:
suspend fun refreshModels(): Response<List<Model>>
return try {
Response.Success(save(entity))
} catch (e: Exception) {
Response.Exception(e)
}
В дальнейшем следует проверять тип полученного ответа:
scope.launch {
val result = repository.refreshModels()
when (result) {
is Response.Success -> Log.e("data", result.data.toString())
is Response.Exception -> showToastError(result.error.message)
}
}
Данный подход хорош тем, что исключенния вообще не доходят до классов фрагментов и активити. Вместо ошибки прилетает обертка, соответствено, сбоя приложения не будет.