Tratamento de erros em Kotlin: try/catch e além — de A a Z

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Tratamento de erros em Kotlin: try/catch e além — de A a Z



O tratamento de erros é uma das tarefas essenciais de qualquer desenvolvedor. Em Kotlin, assim como em outras linguagens modernas, existem várias abordagens para gerenciar situações excepcionais. Neste artigo, abordaremos todos os métodos principais: desde o clássico try/catch até técnicas avançadas com Result, sealed class e Nothing. Você aprenderá a escrever código robusto e legível que lida corretamente com erros.



1. Bloco clássico try/catch/finally



O mecanismo básico de tratamento de exceções em Kotlin é o bloco try/catch. Ele funciona de forma semelhante ao Java, mas com algumas melhorias. Em Kotlin, try é uma expressão que pode retornar um valor.



fun parseNumber(input: String): Int? {    return try {        input.toInt()    } catch (e: NumberFormatException) {        println("Erro de parsing: ${e.message}")        null // retorna null em caso de erro    } finally {        println("O bloco finally sempre é executado")    }}

fun main() { val result = parseNumber("123abc") println(result) // null}


Principais características:

  • try pode ser usado como expressão — o resultado da última expressão no bloco try ou catch torna-se o resultado de todo o bloco.
  • O bloco finally é executado em qualquer caso (mesmo se houver exceção ou return).
  • Kotlin não possui exceções verificadas (checked exceptions), como em Java — isso simplifica o código.


É importante lembrar que o uso excessivo de try/catch torna o código menos legível. Use-o apenas para situações verdadeiramente excepcionais, e não para controle de fluxo.



2. Tipo Result e abordagem funcional



Para um tratamento de erros mais elegante, Kotlin oferece o tipo Result<T>. É uma sealed class que pode ser Success (com o resultado) ou Failure (com a exceção). É ideal para o estilo funcional.



import kotlin.Result

fun divide(a: Int, b: Int): Result<Int> { return try { Result.success(a / b) } catch (e: ArithmeticException) { Result.failure(e) }}

fun main() { val result = divide(10, 0) // Tratamento com when when (result) { is Result.Success -> println("Resultado: ${result.value}") is Result.Failure -> println("Erro: ${result.exception.message}") } // Ou através de métodos result.onSuccess { value -> println("Sucesso: $value") } .onFailure { e -> println("Falha: ${e.message}") } // Transformação val mapped = result.map { it * 2 } // se for failure, permanece failure println(mapped)}


Vantagens do Result:

  • Mostra explicitamente que a função pode terminar com erro.
  • Permite encadeamento de chamadas (map, flatMap, recover).
  • Não requer try/catch no código chamador.


No entanto, Result não é adequado para armazenamento em coleções ou passagem através de limites de corrotinas — para isso, é melhor usar sealed class.



3. Sealed classes para tratamento detalhado de erros



Quando é necessário tratar diferentes tipos de erros de maneiras distintas, sealed class é a escolha ideal. Você pode criar uma hierarquia de erros e tratá-los em um when com cobertura exaustiva.



sealed class NetworkResult<out T> {    data class Success<T>(val data: T) : NetworkResult<T>()    data class NetworkError(val code: Int, val message: String) : NetworkResult<Nothing>()    data class Timeout(val timeout                

Blogs

Book Recommendations