Hello,
In order to provide an accurate circe Encoder/Decoder, I include the HTTP status code as a field on my response:
object HttpError {
implicit val enc: Encoder[HttpError] = e =>
Json.obj(
"error" -> e.error.asJson,
"cause" -> e.cause.asJson,
"status" -> e.status.code.asJson
)
implicit val dec: Decoder[HttpError] = cursor =>
for {
error <- cursor.downField("error").as[String]
cause <- cursor.downField("cause").as[Option[String]]
code <- cursor.downField("status").as[Int]
status = StatusCode(code)
} yield status match {
case StatusCode.InternalServerError => InternalServerError(error, cause)
case StatusCode.Unauthorized => AuthorizationError(error, cause)
...
case _ => GenericHttpError(error, cause, status)
}
}
Instead of manually specifying each error & variant, like so:
def errorResponseMapper: EndpointOutput.OneOf[HttpError, HttpError] =
oneOf[HttpError](
oneOfVariant(
StatusCode.Unauthorized,
jsonBody[AuthorizationError]
),
oneOfVariant(
StatusCode.InternalServerError,
jsonBody[InternalServerError]
),
oneOfDefaultVariant(
jsonBody[HttpError]
)
)
It would be useful to me if I could have a mapper which just uses the status
and jsonBody[HttpError]
. Is there any way to provide a function for the mapping, e.g:
oneOfVariantValue[HttpError](error => statusCode(error.status).jsonBody(error))
Is this possible?