← Назад к вопросам

Что произойдет если не обрабатывать ошибку в корутине?

1.7 Middle🔥 191 комментариев
#Архитектура и паттерны#Многопоточность и асинхронность

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Обработка ошибок в Kotlin Coroutines: последствия игнорирования

Когда разработчик не обрабатывает ошибку в корутине, это приводит к серьезным последствиям для приложения на Android. Корутины построены на принципе структурной обработки исключений – ошибка должна быть обработана внутри той же структуры, где она возникла. Если этого не происходит, поведение зависит от нескольких ключевых факторов: корневого корутина (родительской корутины), контекста выполнения и типа исключения.

Основные механизмы распространения ошибок

  1. Распространение в родительскую корутину Если корутина запущена с помощью launch без собственного обработчика (CoroutineExceptionHandler) и является корневой корутиной (например, запущена в GlobalScope или в CoroutineScope без SupervisorJob), необработанное исключение приводит к:

    • Завершению родительской корутины (если это обычный Job)
    • Распространению исключения наверх по иерархии

    Пример опасного кода:

    // GlobalScope – опасный подход, ошибка не обрабатывается
    GlobalScope.launch {
        throw RuntimeException("Необработанная ошибка!")
    }
    

    В этом случае исключение будет передано в обработчик исключений корневого scope, но если его нет – приложение может завершиться (в зависимости от контекста).

  2. Использование SupervisorJob Если корутина запущена в scope с SupervisorJob, исключение не распространяется на другие корутины в том же scope:

    val supervisorScope = CoroutineScope(SupervisorJob())
    
    supervisorScope.launch {
        throw Exception("Ошибка в первой корутине")
    }
    
    supervisorScope.launch {
        // Эта корутина продолжит работу, даже если первая завершилась с ошибкой
        delay(1000)
        println("Вторая корутина работает")
    }
    

    Однако сама корутина с ошибкой завершится, а исключение будет либо обработано специальным обработчиком, либо проигнорировано (что часто нежелательно).

Практические последствия на Android

  1. Неожиданные сбои UI Если корутина выполняется в Dispatchers.Main и выбрасывает необработанное исключение, это может привести к:

    • Аварийному завершению активности/фрагмента
    • "Зависанию" UI без видимых причин
    • Потере данных (например, несохраненные изменения формы)
  2. Отсутствие пользовательского feedback Пользователь не увидит сообщения об ошибке – приложение может просто прекратить отвечать или закрыться без объяснений.

  3. Проблемы с жизненным циклом Если корутина запущена в lifecycleScope активности и выбрасывает исключение:

    • При активности может произойти неконтролируемое завершение корутины
    • Ошибка может не коррелировать с жизненным циклом компонента

Как правильно обрабатывать ошибки: основные подходы

// 1. Использование try-catch внутри корутины
coroutineScope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        // Логирование или обработка
        logError(e)
        showUserMessage("Произошла ошибка")
    }
}

// 2. Обработчик исключений на уровне CoroutineScope
val handler = CoroutineExceptionHandler { context, exception ->
    println("Caught exception: $exception")
}

val scope = CoroutineScope(Job() + handler)

// 3. Использование async с обработкой результата
coroutineScope.launch {
    val deferred = async { riskyOperation() }
    
    try {
        deferred.await()
    } catch (e: Exception) {
        // Обработка ошибки из deferred
    }
}

// 4. SupervisorJob для независимых корутин
val supervisorScope = CoroutineScope(SupervisorJob() + handler)

Рекомендации для Android разработчиков

  1. Всегда предусматривать обработку ошибок даже в "безопасных" операциях
  2. Использовать CoroutineExceptionHandler для корневых корутин
  3. Логировать все необработанные исключения для дальнейшего анализа
  4. Связывать корутины с жизненным циклом через lifecycleScope или viewModelScope, которые частично управляют ошибками
  5. Для независимых задач использовать SupervisorJob, чтобы ошибка в одной корутине не влияла на другие

Игнорирование обработки ошибок в корутинах приводит к нестабильности приложения, сложностям в отладке и плохому пользовательскому опыту. Структурная обработка исключений в Kotlin предоставляет мощные инструменты – их необходимо использовать систематически для создания надежных Android приложений.

Что произойдет если не обрабатывать ошибку в корутине? | PrepBro