Kotlin coroutines предлагают несколько стратегий для обработки исключений, и правильный подход зависит от того, какой coroutine builder ты используешь.
try/catch блок — оборачивает suspending код непосредственно внутри корутины, чтобы ловить исключения локальноCoroutineExceptionHandler — работает как глобальный обработчик последней инстанции для не перехваченных исключений в корутинах на основе launchsupervisorScope — изолирует сбои дочерних корутин, так что сбой одной не отменяет её соседей или родителяlaunch vs asyncЭти два builder-а обрабатывают исключения по-разному:
launch пробрасывает исключения немедленно в родительскую корутину при сбое:
launch {
throw RuntimeException("launch error") // пробрасывается немедленно
}
async откладывает исключение до явного вызова await():
val deferred = async {
throw RuntimeException("async error") // сохраняется, но не выбрасывается
}
deferred.await() // исключение выбрасывается здесь
Это означает, что с async ты должен вызвать await() внутри try/catch, чтобы корректно обработать ошибку, иначе она может остаться незамеченной.
launch — исключение пробрасывается немедленно; используй CoroutineExceptionHandler или try/catch внутри блокаasync — исключение удерживается до вызова await(); используй try/catch вокруг await()supervisorScope — предотвращает распространение сбоя между соседними корутинами, давая каждой дочерней корутине независимый жизненный циклИспользуй supervisorScope, когда запускаешь несколько независимых корутин, где сбой одной не должен влиять на остальные. Всегда обрабатывай исключения от async, оборачивая await() в try/catch, чтобы избежать скрытых ошибок.
CoroutineExceptionHandler одинаково эффективно может ловить исключения из корутин launch и async как глобальный обработчик.
Новый — ещё не проверен сообществом
Вы