0Pricing
Kotlin Academy · Lección

DSL Raise de Arrow: composición de errores tipados

Utilice el contexto Raise de Arrow y raise() para componer flujos con múltiples errores de forma clara

DSL Raise de Arrow: composición de errores tipados 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.

La limitación del encadenamiento de Either

Encadenar Either con flatMap crea lambdas profundamente anidadas cuando hay varias operaciones secuenciales. El Raise DSL de Arrow (introducido en Arrow 1.2) ofrece una sintaxis más clara, de estilo coroutine, mediante los receptores de contexto o las funciones de extensión de Kotlin.

¿Qué es Raise<E>?

Raise es un contexto que puede elevar (detener el flujo con) un error de tipo E. Una función que puede fallar llama a raise(error) para abortar y propagar el error, de forma similar a lanzar una excepción, pero sin usar excepciones.

El constructor either { }

El constructor either { } crea un Either a partir de un bloque que tiene un Raise en el contexto. Dentro del bloque, use raise(error) si se produce un fallo o simplemente devuelva un valor si la operación es correcta:

import arrow.core.raise.either
import arrow.core.raise.Raise

fun validateAge(age: Int): Either<String, Int> = either {
    if (age < 0) raise("Age cannot be negative")
    if (age > 150) raise("Age too large")
    age
}

bind() — Desenvolver Either dentro de either{}

Dentro de un bloque either { }, llame a .bind() sobre cualquier valor Either para desenvolverlo. Si es un Left, bind() eleva el error automáticamente y detiene el bloque:

fun createUser(name: String, age: Int): Either<String, User> = either {
    val validName = validateName(name).bind()  // raises if Left
    val validAge  = validateAge(age).bind()    // raises if Left
    User(validName, validAge)                  // only reached if both succeed
}

ensure() — Comprobación de condiciones en línea

ensure(condition) { error } es una forma abreviada de if (!condition) raise(error). Mantiene concisa la lógica de validación:

fun validateEmail(email: String): Either<String, String> = either {
    ensure(email.contains("@")) { "Email must contain @" }
    ensure(email.length <= 255) { "Email too long" }
    email
}

ensureNotNull() — Comprobación de nulos con Raise

ensureNotNull(value) { error } desenvuelve un valor anulable o eleva un error si es nulo:

fun findUser(id: Long, repo: UserRepo): Either<UserError, User> = either {
    ensureNotNull(repo.findById(id)) { UserError.NotFound(id) }
}

Raise con receptores de contexto (Arrow 1.2+)

Puede declarar directamente funciones que requieran un contexto Raise, sin envolverlas en either { }:

context(Raise<String>)
fun requirePositive(n: Int): Int {
    ensure(n > 0) { "Must be positive" }
    return n
}

// Called inside either { }
val result = either { requirePositive(-1) }  // Left("Must be positive")

Acumulación de errores con zipOrAccumulate

De forma predeterminada, Raise detiene el flujo ante el primer error. Use zipOrAccumulate() para ejecutar varias validaciones y recopilar todos los errores en una NonEmptyList:

val result: Either<NonEmptyList<String>, User> = either {
    zipOrAccumulate(
        { validateName(name).bind() },
        { validateAge(age).bind() }
    ) { validName, validAge -> User(validName, validAge) }
}

recover { } — Gestión de errores específicos

Use recover { error -> ... } dentro de either { } para gestionar un error elevado específico y proporcionar un valor alternativo, reanudando el cálculo:

val name: String = either {
    findUser(0L).bind().name
}.recover { error ->
    if (error == UserError.NotFound) "Guest" else raise(error)
}.getOrNull() ?: "Guest"

Raise frente al encadenamiento de Either: cuándo usar cada uno

Use either { }.bind() para flujos lineales con varios pasos secuenciales: se lee como código imperativo, pero sigue siendo puro. Use el encadenamiento con flatMap para composiciones breves de dos pasos o al combinarlo con otras bibliotecas funcionales.

Pruebas de funciones basadas en Raise

Realice las pruebas llamando a la función dentro de either { } y comprobando el resultado. Los matchers shouldBeLeft() y shouldBeRight() de Kotest permiten escribir aserciones concisas:

import arrow.core.shouldBeLeft
import arrow.core.shouldBeRight

@Test
fun `negative age returns Left`() {
    validateAge(-1).shouldBeLeft()
}

@Test
fun `valid age returns Right`() {
    validateAge(25).shouldBeRight(25)
}

Comprobación rápida

Dentro de un bloque either { }, ¿qué ocurre al llamar a .bind() sobre un valor Either.Left?

Repaso: Raise DSL de Arrow

Puntos clave:

  • either { } crea un Either a partir de un bloque con Raise en el contexto
  • .bind() desenvuelve Either; detiene el flujo si encuentra un Left
  • ensure(condition) { error } y ensureNotNull(value) { error } permiten realizar comprobaciones en línea
  • zipOrAccumulate() recopila varios errores en lugar de detenerse ante el primero
  • Se lee como código imperativo, aunque sigue siendo puramente funcional

Preguntas frecuentes

¿La lección «DSL Raise de Arrow: composición de errores tipados» es gratis?

Sí — el texto completo de «DSL Raise de Arrow: composición de errores tipados» 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 «DSL Raise de Arrow: composición de errores tipados»?

Utilice el contexto Raise de Arrow y raise() para componer flujos con múltiples errores de forma clara 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 «DSL Raise de Arrow: composición de errores tipados»?

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. Either : gestión de errores tipada sin excepciones
  2. DSL Raise de Arrow: composición de errores tipados
  3. Option y Nullable: cuándo utilizar cada uno
  4. Modelado funcional de dominios con los tipos principales de Arrow
← Volver a Kotlin Academy