0Pricing
Kotlin Academy · Lección

Crear clases de excepciones personalizadas

Defina excepciones específicas del dominio con mensajes y propiedades significativos.

Crear clases de excepciones personalizadas es una lección gratuita de Kotlin Academy en CoddyKit. Esta es la lección 2 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Kotlin Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Kotlin Academy incluye 4 lecciones en total.

¿Por qué utilizar excepciones personalizadas?

Las excepciones personalizadas expresan el significado del dominio: los llamadores pueden capturarlas específicamente, obtener mensajes útiles y actuar de forma diferente según el tipo.

La excepción personalizada más sencilla

Herede de Exception (o de una subclase específica como RuntimeException) y pase un mensaje al constructor de la superclase.

class InvalidEmailException(message: String) : Exception(message)
fun main() {
    try {
        throw InvalidEmailException("missing @")
    } catch (e: InvalidEmailException) {
        println("caught: ${e.message}")
    }
}

Excepción con propiedades

Añada campos para transmitir contexto: estado HTTP, nombre del campo, número de reintentos, etc.

class HttpError(
    message: String,
    val statusCode: Int
) : Exception(message)
fun main() {
    try {
        throw HttpError("Not Found", 404)
    } catch (e: HttpError) {
        println("HTTP ${e.statusCode}: ${e.message}")
    }
}

Excepción con causa

Pase una cause para conservar la excepción original en la cadena.

class DatabaseError(message: String, cause: Throwable) : Exception(message, cause)
fun main() {
    try {
        try { error("connection refused") }
        catch (e: Throwable) { throw DatabaseError("query failed", e) }
    } catch (e: DatabaseError) {
        println("${e.message} (caused by: ${e.cause?.message})")
    }
}

Comprobadas frente a no comprobadas

Kotlin trata todas las excepciones como no comprobadas (no es necesario declarar throws). Por convención, herede de RuntimeException.

class ValidationException(field: String, message: String) :
    RuntimeException("[$field] $message")
fun main() {
    try {
        throw ValidationException("age", "must be positive")
    } catch (e: ValidationException) {
        println(e.message)
    }
}

Jerarquía de excepciones del dominio

Construya una jerarquía para que los llamadores puedan capturar un tipo base para la gestión general o subtipos específicos para casos especiales.

open class AppException(message: String) : RuntimeException(message)
class NotFoundException(what: String) : AppException("$what not found")
class UnauthorizedException : AppException("not authorized")
fun main() {
    val errors = listOf(NotFoundException("user"), UnauthorizedException())
    for (e in errors) {
        try { throw e }
        catch (e: AppException) { println("App error: ${e.message}") }
    }
}

Jerarquía sealed de excepciones

Para conjuntos cerrados de tipos de error, utilice una jerarquía sealed; los llamadores podrán gestionar exhaustivamente todas las variantes.

sealed class ApiError(message: String) : RuntimeException(message) {
    class Timeout : ApiError("timeout")
    class NotFound(val id: String) : ApiError("not found: $id")
    class ServerError(val status: Int) : ApiError("server returned $status")
}
fun describe(e: ApiError) = when (e) {
    is ApiError.Timeout -> "request timed out"
    is ApiError.NotFound -> "id ${e.id} missing"
    is ApiError.ServerError -> "5xx: ${e.status}"
}
fun main() {
    println(describe(ApiError.NotFound("user-42")))
}

Convención de nombres

Termine los nombres de las clases de excepciones personalizadas con Exception o Error para aportar claridad. Utilice el tiempo pasado o un sustantivo (por ejemplo, NotFound, InvalidInput).

class InvalidInputException(msg: String) : RuntimeException(msg)
class UserNotFoundException(id: Int) : RuntimeException("user $id not found")
fun main() {
    try { throw UserNotFoundException(7) }
    catch (e: UserNotFoundException) { println(e.message) }
}

Documentar excepciones

Utilice KDoc @throws para documentar qué excepciones puede lanzar una función.

/**
 * @throws InvalidEmailException if the email is malformed
 */
fun validate(email: String) {
    if ("@" !in email) throw InvalidEmailException("missing @")
}
class InvalidEmailException(m: String) : RuntimeException(m)
fun main() {
    try { validate("nope") }
    catch (e: InvalidEmailException) { println(e.message) }
}

Evitar el uso excesivo de excepciones

Las excepciones deben reservarse para situaciones excepcionales. Para resultados esperados (entrada vacía, campo opcional ausente), prefiera devoluciones anulables, tipos de resultado sealed o valores predeterminados.

fun findUser(id: Int): String? = if (id == 1) "Alice" else null
fun main() {
    val name = findUser(42) ?: "(unknown)"
    println(name) // (unknown), no exception
}

Ejemplo práctico

Una excepción personalizada realista para un cliente de API ficticio, con el estado y el cuerpo de la respuesta.

class ApiException(
    message: String,
    val statusCode: Int,
    val responseBody: String
) : RuntimeException(message)
fun main() {
    try {
        throw ApiException("Bad Request", 400, "{\"error\":\"invalid\"}")
    } catch (e: ApiException) {
        println("[${e.statusCode}] ${e.message}: ${e.responseBody}")
    }
}

Comprobación rápida

¿Qué clase padre se utiliza con mayor frecuencia al definir una excepción de Kotlin específica del dominio?

Resumen

Las excepciones personalizadas expresan el significado del dominio. Herede de RuntimeException o Exception, añada propiedades para aportar contexto, conserve las causas y construya jerarquías para agrupar las capturas. Utilice excepciones sealed para conjuntos cerrados y prefiera tipos anulables o de resultado cuando los errores sean esperados.

Preguntas frecuentes

¿La lección «Crear clases de excepciones personalizadas» es gratis?

Sí — el texto completo de «Crear clases de excepciones personalizadas» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Kotlin Academy, actualiza a CoddyKit PRO. El curso de Kotlin Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Crear clases de excepciones personalizadas»?

Defina excepciones específicas del dominio con mensajes y propiedades significativos. Practicas Kotlin Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Kotlin Academy?

No se requiere experiencia previa. Kotlin Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 2 de 4.

¿Cuánto tiempo toma la lección «Crear clases de excepciones personalizadas»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Kotlin Academy?

Sí. Cada lección de Kotlin Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. try/catch/finally como expresión
  2. Crear clases de excepciones personalizadas
  3. runCatching y Result
  4. Volver a lanzar excepciones y encadenarlas
← Volver a Kotlin Academy