attempt & raiseLefts

Mueve un fallo entre los dos canales que tiene un Stream de Dart: el canal de errores que ve todo listen(onError:), y el canal de valores que lleva Either.

FxEvents<Either<E, T>> FxEvents<T>.attempt<E>(E Function(Object error, StackTrace stackTrace) onThrow) FxEvents<R> FxEvents<Either<L, R>>.raiseLefts() // L extends Object

Lección

Las propias herramientas de error de la capa de eventos — onErrorReturn, onErrorResume, retryOn, retryOnError — hablan todas un Object sin tipar, porque eso es lo que lleva el canal de errores. attempt es el puente hacia la mitad tipada de la librería: cada evento de datos se convierte en un Right, cada evento de error en un Left construido por onThrow. Una vez que el fallo es un Left, el compilador conoce su tipo y un switch sobre el evento no puede olvidarse de manejarlo.

Convierte en el límite de la fuente y quédate después en el canal de valores. Un error de Dart no es terminal, así que la fuente mantiene su suscripción y los eventos posteriores siguen llegando — la misma razón por la que onErrorReturn sustituye por error en vez de rescatar una sola vez. La diferencia es el tipo de resultado: onErrorReturn conserva T eligiendo un marcador de posición; attempt lo cambia a Either<E, T> para que el fallo tenga nombre.

Coloca attempt después de retryOn / retryOnError / FxEvents.retry, nunca antes. Esos operadores vigilan el canal de errores, y no queda nada ahí que reintentar una vez que el error se ha convertido en un valor.

raiseLefts es la otra dirección, solo sobre fallos non-nullable, porque Dart no puede hacer throw de null. Desenvuelve cada Right y vuelve a poner cada Left en el canal de errores, para un límite que entrega el stream a código basado en Stream que espera errores de Dart. Un viaje de ida y vuelta attempt / raiseLefts conserva el valor del fallo y no su stack trace — Left no lleva uno.

Demo 1 · Los errores se convierten en Left, la cadena sigue

Demo 2 · raiseLefts, la otra dirección

Pruébalo tú

Ejercicio: attempt después de retry convierte un fallo reintentado; attempt antes de retry no deja nada en el canal de errores que reintentar.

Relacionado: onErrorReturn / onErrorResume — recuperar en el canal de errores, sin tipar · mapEither — quédate en el canal de valores; un raise se convierte en un Left · Either — el tipo de resultado sellado que envuelven estos operadores