either & el ámbito Raise

Ejecuta un bloque en un ámbito Raise<E>: código en línea recta que puede cortocircuitar con un error tipado. Un E elevado se convierte en Left; un retorno normal, en Right.

Either<E, A> either<E, A>(A Function(Raise<E> r) block) Future<Either<E, A>> eitherAsync<E, A>(FutureOr<A> Function(Raise<E> r) block) Either<E, A> eitherCatching<E, A>(block, E Function(Object thrown, StackTrace st) onThrow) (+ eitherCatchingAsync) on Raise<E>: bind · bindAll · ensure · ensureNotNull · recover(block, onRaise, {onThrow}) · withError · raise

Lección

El constructor le entrega a tu bloque un ámbito r — el port del either { } de Arrow en Kotlin. Todo cuelga de él; escribe r. y descubre el vocabulario completo:

Por dentro esto no es un encadenamiento de flatMap: un bind fallido lanza una señal privada, etiquetada con el ámbito, que el constructor captura en su frontera. Por eso los retornos tempranos, los bucles y los if funcionan sin más dentro del bloque, y por eso los constructores anidados nunca capturan los errores de los demás. eitherAsync es el gemelo asíncrono — mismo vocabulario, con await permitido (elevar errores solo dentro de la misma cadena de awaits).

Demo 1 · ensure & ensureNotNull

Demo 2 · bind — el asesino de la pirámide de flatMap

Demo 3 · recover, withError & raise

Demo 4 · eitherCatching — la frontera de excepciones, precombinada

El parseo real falla por dos vías a la vez: tus reglas lanzan con raise errores tipados, mientras la plataforma (int.parse, jsonDecode) lanza excepciones. eitherCatching es either + catching en un solo builder — el bloque puede hacer raise o lanzar, y el segundo argumento convierte cualquier excepción lanzada en el mismo error tipado. La señal de raise nunca se le entrega. recover acepta la misma cláusula opcional onThrow:, completando el recover(block, recover, catch) de tres cláusulas de Arrow 2.x.

Pruébalo tú

Ejercicio: haz que checkAge falle con un error tipado en vez de lanzar una excepción — ensureNotNull para el parseo, ensure para el límite de edad.

Dos reglas. (1) Nunca devuelvas un pipeline perezoso desde un bloque raise — materialízalo con toList() dentro, o usa los terminales ansiosos de Either; un raise diferido falla ruidosamente con RaiseLeakedError. (2) Nunca uses un catch pelado dentro de un bloque raise — usa catching/catchingAsync, que siempre dejan pasar la señal de cortocircuito.
Relacionado: Either — el tipo frontera · nullable — el gemelo sin información que devuelve T? · acumulación — recoge todos los fallos · errores tipados — guía completa