Introducción: ¿por qué este tema explota en Stack Overflow?
\n\nSi alguna vez has escrito en Kotlin y te has enfrentado a la necesidad de capturar múltiples excepciones diferentes, sabes que puede ser doloroso. Especialmente si vienes de Java, donde el multi-catch (catch (IOException | SQLException e)) es un estándar desde Java 7. En Kotlin es diferente, y muchos desarrolladores se pierden.
\n\nLa pregunta "How to catch many exceptions at the same time in Kotlin?" en Stack Overflow ha acumulado miles de visitas. Y no es casualidad: el manejo de errores es algo con lo que todos se encuentran. Hoy resolveremos este problema de una vez por todas.
\n\nEn este artículo aprenderás:
\n- \n
- Por qué el multi-catch en Kotlin no funciona como en Java \n
- Cómo capturar múltiples excepciones de forma elegante y compacta \n
- Cuándo usar
whenencatchy cuándo usar el clásicoif\n - Ejemplos reales de código en producción \n
¡Allá vamos!
\n\nEl problema: ¿dónde está mi multi-catch?
\n\nEn Java simplemente escribes:
\ntry {\n riskyOperation()\n} catch (IOException | SQLException e) {\n // manejamos igual\n}\n\n\nBonito, conciso, claro. Pero en Kotlin esta sintaxis no existe. Si intentas escribir catch (IOException | SQLException e), el compilador te dirá que no.
¿Por qué? Porque Kotlin optó por la claridad y pureza. Los desarrolladores del lenguaje decidieron que el multi-catch con barra vertical no es exactamente el estilo de Kotlin. Pero eso no significa que no puedas capturar múltiples excepciones. Simplemente se hace de otra manera.
\n\nVeamos tres formas principales.
\n\nForma 1: múltiples bloques catch (la más obvia)
\n\nLa forma más simple es agregar varios bloques catch en secuencia. Kotlin lo soporta perfectamente.
try {\n val data = loadData()\n processData(data)\n} catch (e: IOException) {\n println("Error de entrada/salida: ${e.message}")\n} catch (e: SQLException) {\n println("Error de base de datos: ${e.message}")\n} catch (e: Exception) {\n println("Error desconocido: ${e.message}")\n}\n\n\nVentajas:
\n- \n
- Extremadamente claro: cada tipo de excepción se maneja por separado \n
- Se puede dar lógica diferente para diferentes errores \n
- Excelente legibilidad para principiantes \n
Desventajas:
\n- \n
- Mucha duplicación de código si la lógica de manejo es la misma \n
- Con 5+ excepciones, el bloque se vuelve voluminoso \n
Forma 2: catch con when (elegante y flexible)
\n\nAquí es donde Kotlin muestra todo su esplendor. En lugar de multi-catch, puedes usar when dentro de un solo bloque catch.
try {\n val result = fetchFromNetwork()\n saveToDatabase(result)\n} catch (e: Exception) {\n when (e) {\n is IOException -> handleNetworkError(e)\n is SQLException -> handleDatabaseError(e)\n is SecurityException -> logAndNotify(e)\n else -> throw e // relanzamos si no sabemos cómo manejarlo\n }\n}\n\n\nEste enfoque es un verdadero hallazgo. Permite:
\n- \n
- Manejar diferentes excepciones en un solo lugar \n
- Usar todas las capacidades de
when, incluyendo verificaciones de condiciones \n - Agregar fácilmente nuevos tipos de excepciones \n
Aquí hay un ejemplo más avanzado con condiciones:
\n\ntry {\n connectToService()\n} catch (e: Exception) {\n when {\n e is IOException && e.message?.contains("timeout") == true -> \n println("Tiempo de espera de conexión agotado, reintentando")\n e is IOException -> \n println("Error de red: ${e.message}")\n e is SQLException && e.errorCode == 1045 -> \n println("Error de autenticación en la BD")\n else ->