Где правильнее обработать ошибку получения данных?

Используя 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 шт):

Автор решения: Disf

Можно создать класс-обертку на подобии этой:

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)
    }
}

Данный подход хорош тем, что исключенния вообще не доходят до классов фрагментов и активити. Вместо ошибки прилетает обертка, соответствено, сбоя приложения не будет.

→ Ссылка