Выбор ответа Senior Исключения в корутинах обновлено

Ошибка в async и try вокруг await

Вопрос

Что произойдёт с coroutineScope?

suspend fun load() = coroutineScope {
    val d = async { error("boom") }
    try { d.await() } catch (e: Exception) { "fallback" }
}

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: coroutineScope отменится и бросит boom, несмотря на try. Дочерний async в обычном scope при падении сразу отменяет родителя, не дожидаясь await. try вокруг await действительно поймает исключение, но сам coroutineScope уже в состоянии отмены и после завершения бросит boom наружу.

Варианты ответа

  1. Ошибка поймана, coroutineScope вернёт "fallback"
  2. Ошибка проглотится, функция вернёт null
  3. coroutineScope отменится и бросит boom, несмотря на tryправильный ответ
  4. Код зависнет на await, пока scope отменяется

Разбор

Дочерний async в обычном scope при падении сразу отменяет родителя, не дожидаясь await. try вокруг await действительно поймает исключение, но сам coroutineScope уже в состоянии отмены и после завершения бросит boom наружу. Чтобы изолировать ошибку, используют supervisorScope: там async не трогает родителя, и try у await работает как ожидается.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.