Kotlin协程-优雅地处理来自挂起函数的错误



尝试用从异步方法调用的挂起函数来实现对错误的优雅处理,如何捕获挂起方法引发的错误。

suspend fun findById(id: Long): User? {
throw Exception("my exception") // intentionally throwing to simulate error situation.
return userModel.findById(id) // IO, may throw an error
}

调用方工件,使用IO线程启动

GlobalScope.launch(Dispatchers.IO) {
try {
var userAsync: Deferred<User?>? = null
arguments?.getLong("id")?.let {
userAsync = async { viewModel?.findById(it) } // async for efficiency as i've other async methods too.
}
val data = userAsync?.await()
withContext(Dispatchers.Main) {
user = data // data binding, populating UI fields of user
}
} catch (exception: Exception) {
withContext(Dispatchers.Main) { fault(exception) }
}
}

故障方法

private fun fault(exception: Exception) {
Log.d("User", "fault: ${exception.localizedMessage}") // expecting output
}

当前运行时正在崩溃,希望实现对错误的优雅处理。


尝试2次

尝试在异步块中放置try-catch,但它不喜欢。

var userAsync: Deferred<UserVO?>? = null
arguments?.getLong("id")?.let {
userAsync = async {
try {
delegate?.findById(it)
} catch (e: Exception) {
print(e)
}
}
}

我会使用CoroutineExceptionHandler来使您的协同程序优雅地失败:

1(定义处理程序:

val exceptionHandler = CoroutineExceptionHandler { context, error ->
// Do what you want with the error
Log.d(TAG, error)
}

2(重构要在IO上下文中执行的findById函数,并确保ui代码主安全:

suspend fun findById(id : Int) : User? = withContext(Dispatchers.IO){
when(id){
0 -> throw Exception("not valid")
else -> return@withContext User(id)
}
}
  1. MainScope中启动作业(因此更新ui(,将exceptionHandler传递给启动协同程序生成器以捕获异常:
val exceptionHandler = CoroutineExceptionHandler { _, error ->
// Do what you want with the error
Log.d(TAG, error)
}
MainScope().launch(exceptionHandler) {
val user = delegate?.findById(userId)
user?.let {
Timber.v(it.toString())
}
}

最新更新