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
相关产品推荐
相关产品推荐

