I have a simple code which using tapir
sttp.client3.json._
:
def method(...): Task[MyResponse] =
someLogic().response(asJson[MyResponse]).flatMap(res => ZIO.fromEither(res.body))
But now I want to add here some logic to use custom errors when asJson[MyResponse]
failed.
I created my error hierarchy:
sealed trait MyError extends Throwable
case class MyFirstError (msg: String) extends MyError
case class MySecondError (msg: String) extends MyError
And I changed Task
to IO[MyError, MyResponse]
, but I have no idea how should I return errors when they appeared and return same correct MyResponse
when everything is ok.
I tried smth like this:
def method(...): IO[MyError, MyResponse] =
someLogic().response(asJson[MyResponse]).flatMap{ res =>
res.code match {
case StatusCode.BadRequest => ZIO.fail(MyFristError("my error"))
case StatusCode.Forbidden => ZIO.fail(MySecondError("my other error"))
case _ => ZIO.fromEither(res.body).orDie
}
}
I got an error here Required IO[MyError, MyResponse], Found ZIO[Any, Throwable, MyResponse]
How should I fix this code to return my custom errors depend on the status code and correct response when everything is ok?
I think you're running into this issue on the "catch-all" case:
The
fromEither
is returning someIO[E, A]
my assumption is that theE
is where you're running into theThrowable
. Explicity declaring the types should fix it:fromEither[MyError, MyResponse]
.If adding the types explicity isn't possible, then instead of using
orDie
, you could userefineOrDie { case e: MyError => e }
.