未捕获流中的异常

时间:2020-10-18 09:14:18

标签: android kotlin exception flow

我有一个kotlin流,其中途中抛出异常。不管我做什么,都不会发现异常。

流程如下: 在视图模型中,我具有需要在更改日期后从数据库中重新读取的值。我为此使用了一个切换图。

 val branches:LiveData<List<SCBranch>> = currentDay.switchMap {
    schooldataUseCases.getBranches(it)
            .catch{
                 exception ->withContext(Dispatchers.Main) {
                    Timber.d("catching exception in switchmap")
                    uncaughtException.value = exception.message
                }
            }
            .asLiveData

useCase如下:

override fun getBranches(day:Day): Flow<List<SCBranch>> =
        schooldataRepository.getBranchesForSchoolPeriodFlow(schoolPeriodManager.getSchoolPeriodFor(day.startTime))

schoolPeriodManager选择请求日期的schoolPeriod。如果在请求的日期中未定义schoolPeriod,则会引发异常。我想捕获该异常,并通过另一个liveData'uncaughtexception'通知用户他们选择了无效日期。

A,我的应用程序以致命异常结尾,这确实是schoolPeriodManager抛出的异常。因此,switchmap中的catch块不会捕获异常。

我试图向这样的流程添加一个CoroutineExceptionHandler:

val branches:LiveData<List<SCBranch>> = currentDay.switchMap {
    schooldataUseCases.getBranches(it)
            .asLiveData( exceptionHandler)
}

exceptionHandler也不捕获异常。该应用程序仍然以相同的致命异常结束

我应该如何实现catch块来捕获引发的异常?

1 个答案:

答案 0 :(得分:0)

我有同样的问题,伙计。

为了处理捕获,必须发出该值,例如:

 val branches:LiveData<List<SCBranch>> = currentDay.switchMap {
    schooldataUseCases.getBranches(it)
            .catch { exception ->
                Timber.d("catching exception in switchmap")
                emit(exception.message)
            }
            .asLiveData()

但是,在您的情况下,从catch发出的值在地图上是不同的,因此也许您需要为此创建一个包装器类,例如具有成功内容和catch错误的密封类。 >

    sealed class BranchesState {
        data class Success(val branches: List<Int>) : BranchesState()
        data class Error(val message: String) : BranchesState()
        object Loading : BranchesState()
    }

    val branches: LiveData<BranchesState> = currentDay.switchMap {
        schooldataUseCases.getBranches(it)
            .map { BranchesState.Success(it) as BranchesState }
            .onStart { emit(BranchesState.Loading) }
            .catch { exception ->
                Timber.d("catching exception in switchmap")
                emit(BranchesState.Error(exception.message))
            }
            .asLiveData()

PS:需要在地图上进行强制转换,因为否则将显示错误,表明您要使用的liveData是BranchesState.Success的类型,而不是BranchesState