如何解决Http4s circe 无法解码儿童
我有如下错误模型:
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
在我的路线中,我基于此模型生成 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(_)
)
但问题是我需要添加这个 asInstanceOf,否则 circe 看不到编码器。 我的编码器看起来像:
implicit val encodeHttpError: Encoder[HttpError] = (error: HttpError) =>
Json.obj(("msg",Json.fromString(error.msg)),("cause",Json.fromString(error.cause)))
有没有办法避免在那里做 asInstanceOf?
解决方法
您不能将编码器用于 HttpError
的子类,因为 Encoder
是不变的(如果它是协变的,它将起作用)。
您可以使用的一种解决方案是使用参数化的 def
而不是 val
来定义编码器:
implicit def encodeHttpError[E <: HttpError]: Encoder[E] = (error: E) =>
Json.obj(
("msg",Json.fromString(error.msg)),("cause",Json.fromString(error.cause))
)
这样,您将拥有 HttpError
和 HttpError
的所有子类型的编码器实例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。