Я не могу сказать вам, почему CoroutineExceptionHandler
не уловил исключение, выданное launch
. Но я могу сказать вам 2 вещи -
- Я проверил найденное вами поведение - вы правы, исключение не обнаружено.
- Экспериментируя, я научился ловить исключение в
CoroutineExceptionHandler
.
Вот код, который показывает, как его поймать:
fun f() = runBlocking {
val eh = CoroutineExceptionHandler { _, e -> trace("exception handler: $e") }
val cs1 = CoroutineScope(Dispatchers.Default)
val j1 = cs1.launch(eh + CoroutineName("first")) {
trace("launched")
delay(1000)
throw RuntimeException("error!")
}
trace("joining j1")
j1.join()
val cs2 = CoroutineScope(Dispatchers.Default + eh)
val j2 = cs2.launch(CoroutineName("second")) {
trace("launched")
delay(1000)
throw RuntimeException("error!")
}
trace("joining j2")
j2.join()
trace("after join")
}
f()
Вывод на консоль:
[main @coroutine#1]: joining j1
[DefaultDispatcher-worker-1 @first#2]: launched
[DefaultDispatcher-worker-1 @first#2]: exception handler: java.lang.RuntimeException: error!
[main @coroutine#1]: joining j2
[DefaultDispatcher-worker-1 @second#3]: launched
[DefaultDispatcher-worker-3 @second#3]: exception handler: java.lang.RuntimeException: error!
[main @coroutine#1]: after join
Ключевым выводом является то, что если вы вызовете launch
для пользовательского CoroutineScope
, любой CoroutineExceptionHandler
, предоставленный непосредственно конструктору CoroutineScope
или launch
, будет выполнен, когда в * 1023 будет сгенерировано исключение * ed сопрограмма.
Надеюсь, это поможет !!
UPDATE
Я выяснил, почему исключение не поймано. Смотрите мой ответ здесь .