You'll need to decide what you want to do with Throwable
errors which are not AppError
.
If you decide you want to map them to an AppError
you can do:
method(input).mapError {
case ae: AppError => ae
case other => AppError(other.getMessage)
}
If you want to refine those errors and only keep the ones that are AppError
then you can use one of the refine*
family of operators, which will keep errors that match the predicate and terminate the fiber otherwise.
method(input).refineToOrDie[AppError] // IO[AppError, Boolean]
// Or
method(input).refineOrDie { case ae: AppError => ae } // IO[AppError, Boolean]
Or if you want to assume that all errors from method
are considered "Fiber terminating", then you can use .orDie
to absorb the error and kill the fiber:
method(input).orDie // UIO[Boolean]
Or if you want to recover from the error and handle it a different way then you could use the catch*
family
method(input).catchAll(_ => UIO.succeed(false)) // UIO[Boolean]
Finally if you wanted to have the result mapped into an Either
you could use .either
, which will lift the error out of the error channel and map it into Either[E, A]
method(input).either // UIO[Either[Throwable, Boolean]]
There is a great cheat sheet (though admittedly a bit out of date) here as well