> Что такое CoroutineExceptionHandler (Kotlin, Android)
Уровень: junior · Роль: mobile · Категория: Технические вопросы
Компании: MTS, Юрент, Совкомбанк
Стек: Kotlin, Android
> Пример ответа
Короткий ответ
CoroutineExceptionHandler - это механизм в Kotlin Coroutines для перехвата необработанных исключений, возникающих в корутинах. Он устанавливается через CoroutineContext и вызывается, когда исключение не было обработано внутри корутины. Это аналог Thread.UncaughtExceptionHandler, но для корутин. Используется для централизованной обработки ошибок, например, логирования или показа пользователю.
Подробное объяснение
CoroutineExceptionHandler - это элемент CoroutineContext, который реализует интерфейс CoroutineExceptionHandler. Он перехватывает исключения, которые выходят за пределы корутины и не были обработаны внутри неё (например, через try-catch или runCatching).
Важные особенности:
- Обработчик вызывается только для исключений, которые не были перехвачены внутри корутины.
- Он не работает с исключениями, которые передаются через
CancellationException(отмена корутины) - они обрабатываются отдельно. - Если обработчик не установлен, исключение будет передано в
Thread.uncaughtExceptionHandlerтекущего потока. - В
CoroutineScopeобработчик можно установить черезCoroutineExceptionHandlerв контексте, но дляasyncиlaunchповедение отличается:asyncпередаёт исключение вDeferred, аlaunch- в обработчик. - Обработчик не заменяет
try-catch- он предназначен для глобальной обработки ошибок, а не для локальной.
На практике
На Android CoroutineExceptionHandler часто используется в ViewModel или Application для централизованного логирования ошибок. Например, можно создать общий обработчик, который отправляет ошибку в Crashlytics или показывает сообщение пользователю.
Важно помнить: обработчик не должен выполнять тяжёлые операции или блокировать поток. Он вызывается в контексте, где произошло исключение, поэтому лучше использовать его только для логирования или уведомления.
Пример кода
val handler = CoroutineExceptionHandler { _, throwable -> Log.e("App", "Uncaught coroutine exception", throwable) } val scope = CoroutineScope(Dispatchers.Main + handler) scope.launch { throw RuntimeException("Something went wrong") } // В логах появится сообщение с ошибкой
Пример с async:
val scope = CoroutineScope(Dispatchers.Main + handler) scope.launch { val deferred = async { throw RuntimeException("Error in async") } try { deferred.await() } catch (e: Exception) { // Обработка локально } } // Здесь handler не вызовется, так как исключение перехвачено через await()
Как отвечать на собеседовании
Начни с определения: "это элемент контекста корутины для перехвата необработанных исключений". Затем поясни, когда он срабатывает: только для launch, не для async (если исключение не проброшено через await). Упомяни, что CancellationException не обрабатывается. Приведи пример использования на Android - логирование в Crashlytics. Если спросят про отличие от try-catch, скажи, что try-catch - локальная обработка, а CoroutineExceptionHandler - глобальная.
Что проверяет интервьюер
Интервьюер проверяет:
- Понимание модели исключений в корутинах.
- Знание разницы между
launchиasyncв контексте обработки ошибок. - Понимание, что
CoroutineExceptionHandlerне перехватываетCancellationException. - Умение применять обработчик на практике (например, в Android-приложениях).
- Осознание ограничений: обработчик не заменяет локальную обработку ошибок.
Типичные ошибки
- Утверждение, что
CoroutineExceptionHandlerперехватывает все исключения, включаяCancellationException. - Попытка использовать обработчик для
async- это не сработает, если не вызватьawait(). - Установка обработчика в
SupervisorJobи ожидание, что он перехватит ошибки дочерних корутин - это работает, но только дляlaunch. - Забывают, что обработчик вызывается в контексте, где произошла ошибка, и не должен блокировать поток.
- Использование обработчика вместо
try-catchдля локальной обработки - это неправильно, так как он не даёт доступа к контексту выполнения.
> Похожие задачи по mobile
Что такое reified в inline функциях Kotlin и зачем он нужен
В чем отличие launch от async в Kotlin Coroutines
Какие диспетчеры бывают в Kotlin Coroutines
Может ли data class в Kotlin иметь пустой конструктор
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью