The signature (in the code or in the scaladoc) seems to be rather clear on this topic:
ZIO.fromFuture[A] converts a Future[A] into a ZIO[Any, Throwable, A].
You pass in a Future[Either[Throwable, MyValue]], so it would return a ZIO[Any, Throwable, Either[Throwable, MyValue]] - not a ZIO[Any, Throwable, MyValue] as your code expects.
To transfer the Left case of your Either onto the "error channel" of the ZIO, you have several options, e.g.:
Convert Future[Either[Throwable, MyValue]] to Future[MyValue] and then to ZIO:
def zioMethod(): ZIO[Any, Throwable, MyValue] =
ZIO.fromFuture { implicit ec =>
futureEitherMethod().flatMap {
case Right(myValue) => Future.successful(myValue)
case Left(throwable) => Future.failed(throwable)
}
}
Convert to ZIO[Any, Throwable, Either[Throwable, MyValue]] and then to ZIO[Any, Throwable, MyValue]:
def zioMethod(): ZIO[Any, Throwable, MyValue] = {
val fromFuture: ZIO[Any, Throwable, Either[Throwable, MyValue]] =
ZIO.fromFuture { implicit ec =>
futureEitherMethod()
}
fromFuture.flatMap(ZIO.fromEither)
}
BTW: for me, this compiles without bringing any additional implicits in code: https://scastie.scala-lang.org/dRefNpH0SEO5aIjegV8RKw
Update: alternative (more idiomatic?) solution
As pointed out in the comments by @LMeyer, there's also ZIO.absolve and to me, that seems to be the more ZIO-idiomatic way (I have close to zero experience with ZIO myself):
ZIO.fromFuture { implicit ec =>
futureEitherMethod()
}.absolve