Que métodos de tratamento de erros em corrotinas você conhece?
sobes.tech IA
Resposta da IA
-
Uso de blocos
try...catch. Método padrão para lidar com exceções. Funciona dentro de uma coroutine.// Uso de try-catch suspend fun fetchData(): String { return try { // Operação que pode lançar uma exceção throw Exception("Erro ao carregar dados") "Dados carregados com sucesso" } catch (e: Exception) { "Erro: ${e.message}" } }try...catchnão é adequado para lidar com exceções não capturadas lançadas por coroutines filhas, executadas em outroCoroutineScope. -
CoroutineExceptionHandler. Intercepta exceções não tratadas lançadas por coroutines que são executadas nesteCoroutineScopeou em seusCoroutineScopefilhos.// CoroutineExceptionHandler val handler = CoroutineExceptionHandler { _, exception -> println("Exceção capturada: $exception") } // Uso de CoroutineExceptionHandler GlobalScope.launch(handler) { // Coroutine que pode lançar uma exceção throw Exception("Erro na coroutine") }CoroutineExceptionHandlersó é acionado para exceções não tratadas pelo mecanismo de concorrência estruturada. -
SupervisorJobesupervisorScope. Diferentemente de umJobnormal, quando uma coroutine filha com erro causa a cancelamento doJobpai,SupervisorJobnão cancela oJobpai devido a um erro na coroutine filha.supervisorScopecria umCoroutineScopecom umSupervisorJob.// Uso de supervisorScope suspend fun loadMultipleData() = supervisorScope { val data1 = async { // Pode lançar uma exceção throw Exception("Erro em dados 1") "Dados 1" } val data2 = async { "Dados 2" } // Pode tratar a exceção de uma async específica try { println("Resultado 1: ${data1.await()}") } catch (e: Exception) { println("Erro ao carregar dados 1: ${e.message}") } println("Resultado 2: ${data2.await()}") }Usado para tarefas filhas independentes, onde o erro de uma não deve afetar as outras. Não substitui
try...catchouCoroutineExceptionHandler, mas altera o comportamento de propagação de exceções. -
Propagação de exceções na concorrência estruturada. Por padrão, uma exceção na coroutine filha cancela a coroutine pai e todos os seus irmãos.
// Exemplo de propagação de exceção runBlocking { val job = launch { launch { // Coroutine filha 1 delay(100) throw Exception("Erro na filha 1") } launch { // Coroutine filha 2 delay(200) println("Filha 2 terminou") } } try { job.join() } catch (e: Exception) { println("Exceção capturada no pai: $e") } }Este é o comportamento padrão da concorrência estruturada, que ajuda a evitar vazamentos de recursos e estados.
-
Uso de
asynccomawait(). As exceções lançadas emasyncnão se propagam automaticamente. Elas ficam armazenadas emDeferrede são lançadas apenas ao chamarawait().// Tratamento de exceções com async/await suspend fun safeAsyncCall() = coroutineScope { val deferred = async { throw Exception("Erro em async") "Resultado de async" } try { val result = deferred.await() println("Resultado: $result") } catch (e: Exception) { println("Exceção capturada de async: ${e.message}") } }Isso permite tratar erros de forma seletiva para cada tarefa assíncrona.
| Método | Propósito | Trata uncaught? | Altera propagação? |
|---|---|---|---|
try...catch |
Tratamento de exceções na coroutine atual | Não | Não |
CoroutineExceptionHandler |
Captura exceções não tratadas no Scope | Sim | Não |
SupervisorJob/Scope |
Altera o comportamento de propagação de exceções | Não | Sim |
| Concurrency estruturada | Cancelamento automático em erro | Sim | Sim |
async + await() |
Propagação adiada de exceções | Não | Sim (antes do await) |