Обработчик во вложенном launch не перехватит ошибку: дочерняя корутина передаст её родителю. Ошибка отменит обычный Job и будет обработана как неперехваченная.
Разбор поведения кода с CoroutineExceptionHandler
Обработчик во вложенном launch не перехватит ошибку: дочерняя корутина передаст её родителю. Ошибка отменит обычный Job и будет обработана как неперехваченная.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Определить, какое действие произойдёт при запуске следующего фрагмента кода.
fun main() {
val coroutineExceptionHandler = CoroutineExceptionHandler { coroutineContext, exception ->
println("Handle $exception in CoroutineExceptionHandler")
}
val topLevelScope = CoroutineScope(Job())
topLevelScope.launch {
launch(coroutineExceptionHandler) {
throw RuntimeException("RuntimeException in nested coroutine")
}
}
}
Ответ
Обработчик во вложенном launch не перехватит ошибку: дочерняя корутина передаст её родителю. Ошибка отменит обычный Job и будет обработана как неперехваченная.
Вложенный launch — не корневая корутина, и установленный на нём CoroutineExceptionHandler не заменяет распространение ошибки к родителю. Внешний launch обработчика не имеет. Для такой структуры handler нужно передать внешнему launch либо включить в контекст исходного scope.
Handler не восстанавливает упавшую корутину; ожидаемую ошибку обрабатывают try/catch внутри выполняемой операции. Отдельная тонкость примера: main сразу заканчивается, не ожидая launch, поэтому увидеть какой-либо вывод или stack trace до завершения процесса не гарантируется.
Источник: kotlinlang.org.