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

标签 android kotlin error-handling try-catch kotlin-coroutines

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

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 放在异步 block 中,但它不喜欢它。
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) 重构您的 findById 函数以在 IO 上下文中执行并使您的 ui 代码主要安全:
suspend fun findById(id : Int) : User? = withContext(Dispatchers.IO){
    when(id){
        0 -> throw Exception("not valid")
        else -> return@withContext User(id)
    }
}
  • 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())
            }
    }
    

    关于android - Kotlin 协程 - 优雅地处理来自挂起函数的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63948153/

    相关文章:

    android - 我的开关 (view.getId()) 不起作用

    android - 从 GregorianCalendar 获取星期几

    java - 不幸的是 MyApp 已停止。我该如何解决这个问题?

    java - 在 Java 中解析 XML 文件并输出所有错误

    xcode - iTunes Store操作失败,错误ITMS-90159 : “Invalid provisioning profile…”

    android - 删除 AlertDialog 背景

    android - 在Android中,如何在运行时找到手机正在运行的ROM和内核?

    android - Kotlin:尝试将以下函数添加到全局共享文件以在多个 Activity 中使用,但不断收到不同的错误

    Java NumberFormat 在 "UP"模式下舍入不正确

    android - 为什么我的新Admob单元没有任何广告?