android-协程中未捕获到异常
作者:互联网
我似乎无法在协程中完成错误处理.我一直在阅读许多文章和exception handling documentation,但似乎无法正常工作.
这是我的设置:
我的ViewModel用它的范围启动协程
class MyViewModel(private var myUseCase: MyUseCase) : ViewModel() {
private val viewModelJob = Job()
private val uiScope = CoroutineScope(Dispatchers.Main + viewModelJob)
fun doSomething() {
uiScope.launch {
try {
myUseCase()
} catch (exception: Exception) {
// Do error handling here
}
}
}
}
我的UseCase仅处理一些逻辑,在这种情况下,是某种验证器
class MyUseCase(private val myRepository: MyRepository) {
suspend operator fun invoke() {
if (checker()) {
throw CustomException("Checker Failed due to: ...")
}
myRepository.doSomething()
}
}
然后我的存储库只处理网络层/本地层
object MyRepository {
private val api = ... // Retrofit
suspend fun doSomething() = api.doSomething()
}
这是我的改造界面
interface MyInterface {
@POST
suspend fun doSomething()
}
ViewModel的try / catch可以处理Retrofit调用中的错误,但是无法捕获UseCase抛出的CustomException中的错误.从我一直阅读的文章来看,这应该可行.如果我使用异步,则可以等待并消耗该错误,但是在这种情况下,我不必使用异步,因此我一直在解决这个问题.我可能会迷路.
任何帮助将不胜感激!提前致谢!
编辑:
这是我得到的错误日志:
com.example.myapp.domain.errors.CustomException
at com.example.myapp.domain.FeatureOne$invoke$2.invokeSuspend(FeatureOne.kt:34)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:238)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:742)
该错误直接指向显式throw语句.
解决方法:
尝试使用CoroutineExceptionHandler是解决协程内部异常的解决方法.
CoroutineExceptionHandler上下文元素用作协程的通用catch块,在协程中可能发生自定义日志记录或异常处理.它类似于使用Thread.uncaughtExceptionHandler.
如何使用它?
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
val job = GlobalScope.launch(handler) {
throw AssertionError()
}
val deferred = GlobalScope.async(handler) {
throw ArithmeticException() // Nothing will be printed, relying on user to call
deferred.await()
}
joinAll(job, deferred)
在ViewModel中,确保uiScope使用SupervisorJob而不是Job. SupervisorJob可以单独处理其孩子的失败.与SupervisorJob不同,工作将被取消
如果您将2.1.0用于AAC Lifecycle和ViewModel,请改用viewModelScope扩展.
标签:kotlin,kotlin-coroutines,android 来源: https://codeday.me/bug/20191108/2005291.html