捕获协程启动调用的错误

时间:2020-07-27 14:43:35

标签: kotlin kotlin-coroutines

在以下代码中:

private fun executeCognitoRequest(result: MethodChannel.Result, block: suspend CoroutineScope.() -> Any?) {
  try {
    CoroutineScope(Dispatchers.Default).launch {
      val requestResult = block()
      withContext(Dispatchers.Main) {
        result.success(requestResult)
      }
    }
  } catch (exception: Exception) {
    val cognitoErrorType = CognitoErrorType.getByException(exception)
    result.error(cognitoErrorType.code, null, null)
  }
}

如果对block的调用引发,会被捕获吗?

1 个答案:

答案 0 :(得分:1)

它将被捕获,但是代码的问题是您违反了结构化并发的原理,并在GlobalScope中启动了协程。因此,如果您从这样的主要功能测试代码:

fun main() {
    runBlocking {
        executeCognitoRequest(MethodChannel.Result()) {
            funThatThrows()
        }
    }
}

整个程序将在协程完成执行之前结束。

这是编写函数的方式:

private fun CoroutineScope.executeCognitoRequest(
        result: MethodChannel.Result,
        block: suspend CoroutineScope.() -> Any?
) {
    try {
        launch(Dispatchers.IO) {
            val requestResult = block()
            withContext(Dispatchers.Main) {
                result.success(requestResult)
            }
        }
    } catch (exception: Exception) {
        val cognitoErrorType = CognitoErrorType.getByException(exception)
        result.error(cognitoErrorType.code, null, null)
    }
}

现在,您的功能是CoroutineScope的扩展,并且launch被该接收者自动调用。另外,要阻止IO调用,您不应该使用Default调度程序。

但是,我发现您的高级设计很奇怪,您从阻塞代码开始,然后将其变成异步的,面向回调的代码。协程可以帮助您摆脱回调。