我有如下的错误模型:
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?
发布于 2021-01-20 20:49:33
你不能对它的子类使用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的编码器实例。
https://stackoverflow.com/questions/65807131
复制相似问题