[英]Http4s circe can not decode children
I have error model like:我有错误 model 像:
sealed trait HttpError {
val msg: String
val cause: String
}
final case class HttpDecodingError(cause: String) extends HttpError {
override val msg: String = "Decoding error"
}
final case class HttpInternalServerError(msg: String, cause: String) extends HttpError
case object HttpUnauthorizedError extends HttpError {
override val msg: String = "Invalid credentials"
override val cause: String = ""
}
final case class HttpBadRequestError(msg: String, cause: String) extends HttpError
in my route I generate http error type based on this model ie:在我的路线中,我根据此 model 生成 http 错误类型,即:
.foldM(
{
case error: HttpDecodingError => BadRequest(error.asInstanceOf[HttpError])
case error: HttpInternalServerError => InternalServerError(error.asInstanceOf[HttpError])
case HttpUnauthorizedError => Unauthorized(withChallenge("Invalid credentials"))
case error: HttpBadRequestError => BadRequest(error.asInstanceOf[HttpError])
},
Ok(_)
)
but problem is that I need to add this asInstanceOf, otherwise circe does not see encoder.但问题是我需要添加这个 asInstanceOf,否则 circe 看不到编码器。 My encoder looks like:
我的编码器看起来像:
implicit val encodeHttpError: Encoder[HttpError] = (error: HttpError) =>
Json.obj(("msg", Json.fromString(error.msg)), ("cause", Json.fromString(error.cause)))
is there a way to avoid doing asInstanceOf there?有没有办法避免在那里做 asInstanceOf ?
You can't use encoder for HttpError
for it's subclasses, because Encoder
is invariant (it would work if it would be covariant).您不能将编码器用于
HttpError
的子类,因为Encoder
是不变的(如果它是协变的,它将起作用)。
One solution you could use is to define encoder using parametrized def
instead of val
:您可以使用的一种解决方案是使用参数化
def
而不是val
定义编码器:
implicit def encodeHttpError[E <: HttpError]: Encoder[E] = (error: E) =>
Json.obj(
("msg", Json.fromString(error.msg)),
("cause", Json.fromString(error.cause))
)
This way you'd have instance of encoder for all subtypes of HttpError
as well as for HttpError
.这样,您将拥有 HttpError 的所有子类型以及
HttpError
的编码器HttpError
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.