You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Clean Architecture场景下UseCase抛出异常无法捕获如何解决?

问题根源

你在UseCase的execute方法中,参数校验失败直接抛出异常的时机,早于Flow对象的创建和返回流程。Flow提供的catch运算符只能捕获Flow内部执行过程中产生的异常,而你现在的异常是在调用execute方法还没拿到Flow实例的时候就抛出来了,自然不会被catch捕获,直接触发协程未捕获异常导致崩溃。
Firebase相关的异常是在Flow内部执行的时候抛出的,所以可以被正常捕获。

修复方案

只需要调整RegisterUseCase的实现,把参数校验逻辑放到Flow内部执行即可,修改后代码如下:

class RegisterUseCase @Inject constructor(
    private val firebaseAuthRepository: FirebaseAuthRepository
) {
    suspend fun execute(email: String, password: String): Flow<User> = flow {
        val trimmedEmail = email.trim()
        val trimmedPassword = password.trim()
        // 校验逻辑移到flow块内部
        if (trimmedEmail.isEmpty() && trimmedPassword.isEmpty()) {
            throw Exception("Please fill both field")
        }
        if (trimmedEmail.isEmpty()) throw Exception("Please give email")
        if (trimmedPassword.isEmpty()) throw Exception("Please give password")
        // 发射仓库返回的Flow的所有元素
        emitAll(firebaseAuthRepository.register(trimmedEmail, trimmedPassword))
    }
}

这样校验逻辑产生的异常就属于Flow执行过程中的异常,会被ViewModel里的catch运算符捕获,封装为Resource.Error后发送到Fragment,正常弹出Toast展示错误信息。

其他注意事项

你贴的代码里还有两处笔误需要修正:

  • LoginViewModel中注入的是registerUseCase,但调用时写的是loginUseCase.execute,需要统一变量名
  • Fragment中获取的ViewModel是RegistrationViewModel,但你贴的ViewModel类名是LoginViewModel,需要保持命名一致

内容的提问来源于stack exchange,提问作者Aminul Haque Aome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 12:36:04