首页 > 解决方案 > 如何使用 Flows 处理数据库调用错误

问题描述

通常我从我的 dao 挂起函数返回:

@Dao
interface DataDao {
    @Query("SELECT * FROM data")
    fun getAllData(): List<Data>
}

并处理存储库中的调用:

class DataRepository(
    private val dataDao: DataDao
) {
    fun getAllData(): Flow<DataState> = flow {
        val cacheResult = safeDatabaseCall(dispatcher = Dispatchers.IO) { dataDao.getAllData() }

    //handle cacheResult, convert to DataState, emit DataState values

    }.flowOn(Dispatchers.IO)

}

具有一般的乐趣:

suspend fun <T> safeDatabaseCall(
    dispatcher: CoroutineDispatcher,
    cacheCall: suspend () -> T?
): CacheResult<T?> {
    return withContext(dispatcher) {
        try {
            withTimeout(10000L) {
                CacheResult.Success(cacheCall.invoke())
            }
        } catch (t: Throwable) {
            when (t) {
                is TimeoutCancellationException -> {
                    CacheResult.Error("Timeout error")
                }
                else -> {
                    CacheResult.Error("Unknown error")
                }
            }
        }
    }
}

问题是我想要返回fun getAllData(): Flow<List<Data>>而不是fun getAllData(): List<Data>为了获得即时更新,但是如果我从 Dao 返回 Flow,我无法使用安全调用处理调用并捕获错误。我考虑过收集数据,但如果我正在收集数据,那么调用已经完成而没有错误处理

基本上我需要缓存结果返回CacheResult<Data>而不是CacheResult<Flow<Data>>

如何解决问题并在从 Dao 返回 Flow 时进行通用 safeDatabaseCall?

标签: androidkotlinandroid-roomkotlin-coroutines

解决方案


推荐阅读