final case class Safe[-I, +O, +E](alterand: Stage[I, O, E]) extends Alterator[Stage[I, O, E], I, O, Either[Throwable, E]], SafeStage[I, O, Either[Throwable, E]]
A decorator that catches non-fatal exceptions thrown by the inner stage and converts them into h8io.stages.Status.Complete error values.
The error type is widened from E to Either[Throwable, E]:
Errors already carried by the inner stage are wrapped as Right(e).
Exceptions caught during apply are reported as Left(throwable) in a Yield.None(Status.error(Left(e)), this).
Only non-fatal exceptions (matched by scala.util.control.NonFatal) are caught; fatal errors such as OutOfMemoryError propagate normally.
The evolution is mapped so that every continuation stage remains wrapped in Safe, maintaining exception safety across the entire pipeline.
Safe is a crutch for the simplest cases — ''stateless'' stages. Per the ''Lifecycle'' contract in h8io.stages.Stage, a stage that throws from apply has already released its own resources, so the recovered continuation simply reuses the inner stage — retrying it on the next input — and carries a no-op dispose. A stage that owns resources should be made safe by itself instead of being wrapped: extend h8io.stages.base.SafeStage and supply a recover with the appropriate cleanup (the h8io.stages.base.ConstEvolution overload taking a dispose function exists for exactly this).
Type parameters
E
the original error type of the inner stage (covariant)
override def skip(): Evolution[I, O, Either[Throwable, E]]
Returns this stage's Evolution without consuming an input.
Returns this stage's Evolution without consuming an input.
Called instead of apply whenever the stage takes part in a run but has nothing to process: the upstream yielded no output, or a binary operator excluded this branch. The evolution must be the one the stage would have returned had it run. Like apply, skip() may perform side effects — a decorator, for instance, may advance or release the inner stage it owns.
Composes this stage with that, feeding this stage's output into it. See the ''Composition'' section above for what happens when there is no output to feed.
Composes this stage with that, feeding this stage's output into it. See the ''Composition'' section above for what happens when there is no output to feed.