Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

codec with status code #1

Closed
wants to merge 11 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import zio.http.endpoint._
private[endpoint] final case class EndpointClient[P, I, E, O, M <: EndpointMiddleware](
endpointRoot: URL,
endpoint: Endpoint[P, I, E, O, M],
codecMapping: Map[Int, Codec[Response, Throwable, E]]
) {
def execute(client: Client, invocation: Invocation[P, I, E, O, M])(
mi: invocation.middleware.In,
Expand All @@ -43,30 +44,30 @@ private[endpoint] final case class EndpointClient[P, I, E, O, M <: EndpointMiddl
Header.Accept(MediaType.application.json, MediaType.parseCustomMediaType("application/protobuf").get),
)

client.request(withDefaultAcceptHeader).orDie.flatMap { response =>
if (response.status.isSuccess) {
endpoint.output.decodeResponse(response).orDie
} else {
// Preferentially decode an error from the handler, before falling back
// to decoding the middleware error:
val handlerError =
endpoint.error
.decodeResponse(response)
.map(e => alt.left(e))
.mapError(t => new IllegalStateException("Cannot deserialize using endpoint error codec", t))
client
.request(withDefaultAcceptHeader)
.orDie
.flatMap { response =>
val decoder = if (response.status.isSuccess) {
endpoint.output.decodeResponse(response)
} else {
// Handle errors based on status code using codecMapping
val statusCode = response.status.code
codecMapping.get(statusCode) match {
case Some(codec) =>
codec
.decodeResponse(response)
.mapError(t => new IllegalStateException(s"Cannot decode response for status $statusCode", t))

val middlewareError =
invocation.middleware.error
.decodeResponse(response)
.map(e => alt.right(e))
.mapError(t => new IllegalStateException("Cannot deserialize using middleware error codec", t))

handlerError.catchAllCause { handlerCause =>
middlewareError.catchAllCause { middlewareCause =>
ZIO.failCause(handlerCause ++ middlewareCause)
case None =>
ZIO.fail(new IllegalStateException(s"No codec found for status $statusCode"))
}
}.orDie.flip
}

decoder.orDie
}
.catchAll { cause =>
ZIO.fail(new IllegalStateException("Error decoding response", cause))
}
}
}
}
Loading