I have a weird problem with error middleweare or I'm using it in wrong way. I would like to add error middleware to my tapir routes and catch all errors from "inside" application. I have simple tapir route:
object SomeApi{
val zServerLogic = SomeTapirEndpoint.someRoute.zServerLogic(_ => ZIO.succeed(MyEmptyResponse))
def myApiRoutes: HttpApp[Any, Throwable] =
ZioHttpInterpreter().toHttp(
zServerLogic
)
}
I also added it to server when it starts:
_ <- Server
.start(
port = config.port,
http = myapis @@ ErrorMiddleware.errorMiddleware
)
.exitCode
Error middleware looks like below:
object ErrorMiddleware {
val errorMiddleware = new HttpMiddleware[Any, Throwable] {
override def apply[R1 <: Any, E1 >: Throwable](
http: HttpApp[R1, E1]
) =
http.catchAll { ex =>
val errorResponse: ZIO[Any, IOException, MyResponse] = for {
_ <- ZIO.logError(s"Logic failed: ${ex.toString}")
} yield MyResponse("FAIL")
ZIO.succeed(errorResponse)
}
}
}
My questions are:
- How I could return my custom response instead of one from
zhttp.http? - How could I catch all errors from
tapirroutes - it looks liketapircatch all errors inzServerLogicand catch all exceptions there and return justEither, so my error middleware always return right side. How could I fix this to catch all errors from application? For example when I put wrong endpoint url or something bad happened during processing logic?
Is it possible to create something similar to Akka's rejection handler to handle all errors on API side? Or maybe there is other solution?