代码之家  ›  专栏  ›  技术社区  ›  A. Cedano

如何在UIState中包含错误案例?

  •  0
  • A. Cedano  · 技术社区  · 3 月前

    我试图捕捉ViewModel中的任何错误情况并更新UIState,但它不起作用。

    这是处理不同响应的密封接口:

    sealed interface UniversalisUiState {
        data object Loading : UniversalisUiState
    
        data class UniversalisData(
            val selectedTopicId: String,
            val topics: UniversalisResource,
        ) : UniversalisUiState
    
        data object Empty : UniversalisUiState
    
        data class UniversalisError(
            val message: String,
        ) : UniversalisUiState
    
    }
    

    在the ViewModel 相关代码为:

    val uiState: StateFlow<UniversalisUiState> = combine(
        selectedTopicId,
        getUniversalisUseCase.invoke(
            date = selectedDate.value,
            title = route.initialTopicId!!,
            selectedTopicId = LiturgyHelper.liturgyByName(route.initialTopicId!!)
                .toString()
        ).catch {
            //NOT WORKING *******
            //emit(UniversalisUiState.UniversalisError(it.message))
            Timber.d("aaa", it.message)
        },
        UniversalisUiState::UniversalisData,
    ).stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000),
        initialValue = Loading,
    )
    

    用例 :

    class GetUniversalisUseCase @Inject constructor(
        private val universalisRepository: UniversalisRepository,
        private val userDataRepository: UserDataRepository,
    ) {
    
        operator fun invoke(
            date: Int,
            selectedTopicId: String,
            title: String
        ): Flow<UniversalisResource>
        {
            return combine(
                userDataRepository.userData,
                universalisRepository.getUniversalisByDate(
                    UniversalisResourceQuery(
                        filterDate = date,
                        selectedTopic = selectedTopicId.toInt()
                    )
                ),
            ) { userData, universalis ->
                if (universalis.todayDate == 0 && selectedTopicId != "30") {
                    universalisRepository.insertFromRemote(
                        UniversalisResourceQuery(
                            date,
                            selectedTopicId.toInt()
                        )
                    )
                }
                UniversalisResource(
                    date = universalis.todayDate, 
                    title = title,
                    name = "",
                    id = selectedTopicId.toInt(),
                    data = universalis,
                    dynamic = userData
                )
            }
        }
    }
    

    我如何做到这一点: emit(UniversalisUiState.UniversalisError(it.message)) 何时发现错误?我可以看到错误 Timber ,但我不能发射 UniversalisError .

    1 回复  |  直到 3 月前
        1
  •  1
  •   tyg    3 月前

    既然你想发射一个 UniversalisUiState ,你需要移动 catch 之后 当流已经是这种类型时,组合:

    val uiState: StateFlow<UniversalisUiState> = combine(
        selectedTopicId,
        getUniversalisUseCase.invoke(
            date = selectedDate.value,
            title = route.initialTopicId!!,
            selectedTopicId = LiturgyHelper.liturgyByName(route.initialTopicId!!)
                .toString()
        ),
        UniversalisUiState::UniversalisData,
    ).catch<UniversalisUiState> {
        emit(UniversalisUiState.UniversalisError(it.message))
        Timber.d("aaa", it.message)
    }.stateIn(
        scope = viewModelScope,
        started = SharingStarted.WhileSubscribed(5_000),
        initialValue = UniversalisUiState.Loading,
    )
    

    您可能需要明确指定接口 普遍性 作为catch的泛型类型,Kotlin可以正确推断结果流的类型。