Kotlin supervisorScope fails even though wrapped in try catch.

huangapple go评论54阅读模式
英文:

Kotlin supervisorScope fails even though wrapped in try catch

问题

以下是翻译好的部分:

考虑以下代码

```kotlin
coroutineScope {
  try {
    supervisorScope { launch { error("") } }
  } catch (t: Throwable) {
    println("logs and stuff")
  }
}

运行此代码,我期望在输出中看到 logs and stuff,但它会将异常传播到原始范围,除非已安装了 CoroutineExceptionHandler,否则将失败。

问题是:这是设计如此,还是一个错误(如果是错误,我会提出问题)?

附言:切换到内部的 coroutineScope "修复" 了这个问题

coroutineScope {
  try {
    coroutineScope { launch { error("") } }
  } catch (t: Throwable) {
    println("现在你会看到它")
  }
}

<details>
<summary>英文:</summary>

Considering such code: 

```kotlin
coroutineScope {
  try {
    supervisorScope { launch { error(&quot;&quot;) } }
  } catch (t: Throwable) {
    println(&quot;logs and stuff&quot;)
  }
}

running this code, I'd expect to see logs and stuff in the output, but it propagates exception all the way up to the origin scope, which will fail unless it has CoroutineExceptionHandler installed.

Question is: is this by design, or a bug (if so — will open an issue)?

P.S. Switching to inner coroutineScope "fixes" the issue

coroutineScope {
  try {
    coroutineScope { launch { error(&quot;&quot;) } }
  } catch (t: Throwable) {
    println(&quot;now you&#39;ll see it&quot;)
  }
}

答案1

得分: 2

This is working as designed.

The error in your first example does not actually propagate to the outer scope. Instead the error is captured by the supervisor scope, and the outer scope continues running normally without encountering an error. This is the expected behavior of a supervisor scope, and it's why the catch block never runs.

You can demonstrate this by adding some more code after the catch block. Code inside the outer scope but after the catch block will continue to run as normal, indicating that no error was encountered in the outer scope.

suspend fun main(): Unit = coroutineScope {
    try {
        supervisorScope { launch { error(&quot;&quot;) } }
    } catch (t: Throwable) {
        println(&quot;you won&#39;t see this&quot;)
    }
    println(&quot;but you will see this&quot;)
}

Since the error doesn't propagate outside the supervisor scope, it is instead passed to the scope's uncaught exception handler. That's why you see the error being printed to the standard error stream. It does not indicate that the application crashed.

英文:

This is working as designed.

The error in your first example does not actually propagate to the outer scope. Instead the error is captured by the supervisor scope, and the outer scope continues running normally without encountering an error. This is the expected behaviour of a supervisor scope, and it's why the catch block never runs.

You can demonstrate this by adding some more code after the catch block. Code inside the outer scope but after the catch block will continue to run as normal, indicating that no error was encountered in the outer scope.

suspend fun main(): Unit = coroutineScope {
    try {
        supervisorScope { launch { error(&quot;&quot;) } }
    } catch (t: Throwable) {
        println(&quot;you won&#39;t see this&quot;)
    }
    println(&quot;but you will see this&quot;)
}

Since the error doesn't propagate outside the supervisor scope, it is instead passed to the scope's uncaught exception handler. That's why you see the error being printed to the standard error stream. It does not indicate that the application crashed.

huangapple
  • 本文由 发表于 2023年3月15日 20:44:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75744890.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定