Выбор ответа 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 наружу.
Варианты ответа
- Ошибка поймана,
coroutineScopeвернёт"fallback" - Ошибка проглотится, функция вернёт
null coroutineScopeотменится и броситboom, несмотря наtryправильный ответ- Код зависнет на
await, пока scope отменяется
Разбор
Дочерний async в обычном scope при падении сразу отменяет родителя, не дожидаясь await. try вокруг await действительно поймает исключение, но сам coroutineScope уже в состоянии отмены и после завершения бросит boom наружу. Чтобы изолировать ошибку, используют supervisorScope: там async не трогает родителя, и try у await работает как ожидается.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Ещё по теме «Исключения в корутинах»
- Где работает CoroutineExceptionHandler
- Ошибки в launch и async
- Распространение исключений
- CoroutineExceptionHandler в дочерней корутине
- launch(SupervisorJob()) внутри scope
- Путь необработанного исключения из дочернего launch
- async в корне и потерянная ошибка
- coroutineScope отменяет соседей