Manejo de errores en Kotlin: try/catch y más allá — de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Manejo de errores en Kotlin: try/catch y más allá — de la A a la Z



El manejo de errores es una de las tareas clave de cualquier desarrollador. En Kotlin, como en otros lenguajes modernos, existen varios enfoques para gestionar situaciones excepcionales. En este artículo, analizaremos todos los métodos principales: desde el clásico try/catch hasta técnicas avanzadas con Result, sealed class y Nothing. Aprenderá a escribir código robusto y legible que maneje los errores correctamente.



1. Bloque clásico try/catch/finally



El mecanismo básico de manejo de excepciones en Kotlin es el bloque try/catch. Funciona igual que en Java, pero con algunas mejoras. En Kotlin, try es una expresión que puede devolver un valor.



fun parseNumber(input: String): Int? {    return try {        input.toInt()    } catch (e: NumberFormatException) {        println("Error de análisis: ${e.message}")        null // devolvemos null en caso de error    } finally {        println("El bloque finally siempre se ejecuta")    }}

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


Características clave:

  • try se puede usar como expresión: el resultado de la última expresión en el bloque try o catch se convierte en el resultado de todo el bloque.
  • El bloque finally se ejecuta en cualquier caso (incluso si hubo una excepción o un return).
  • Kotlin no tiene excepciones verificadas (checked exceptions) como Java, lo que simplifica el código.


Es importante recordar que abusar de try/catch hace que el código sea menos legible. Úselo solo para situaciones realmente excepcionales, no para controlar el flujo.



2. Tipo Result y enfoque funcional



Para un manejo de errores más elegante, Kotlin ofrece el tipo Result<T>. Es una clase sealed que puede ser Success (con un resultado) o Failure (con una excepción). Es ideal para el 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) // Manejo con when when (result) { is Result.Success -> println("Resultado: ${result.value}") is Result.Failure -> println("Error: ${result.exception.message}") } // O mediante métodos result.onSuccess { value -> println("Éxito: $value") } .onFailure { e -> println("Fallo: ${e.message}") } // Transformación val mapped = result.map { it * 2 } // si es failure, seguirá siendo failure println(mapped)}


Ventajas de Result:

  • Muestra explícitamente que la función puede fallar.
  • Permite encadenar llamadas (map, flatMap, recover).
  • No requiere try/catch en el código que llama.


Sin embargo, Result no está diseñado para almacenarse en colecciones ni para transmitirse a través de los límites de las corrutinas; para eso es mejor usar sealed class.



3. Clases sealed para el manejo detallado de errores



Cuando necesita manejar diferentes tipos de errores de manera distinta, sealed class es la opción ideal. Puede crear una jerarquía de errores y manejarlos en un when con cobertura exhaustiva.



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