首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Http4s circe无法解码孩子

Http4s circe无法解码孩子
EN

Stack Overflow用户
提问于 2021-01-20 17:56:20
回答 1查看 46关注 0票数 1

我有如下的错误模型:

代码语言:javascript
复制
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错误类型,即:

代码语言:javascript
复制
.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看不到编码器。我的编码器看起来像这样:

代码语言:javascript
复制
implicit val encodeHttpError: Encoder[HttpError] = (error: HttpError) =>
    Json.obj(("msg", Json.fromString(error.msg)), ("cause", Json.fromString(error.cause)))

有没有办法避免在那里做asInstanceOf?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-20 20:49:33

你不能对它的子类使用HttpError的编码器,因为Encoder是不变的(如果它是协变的,它就可以工作)。

可以使用的一种解决方案是使用参数化的def而不是val来定义编码器

代码语言:javascript
复制
implicit def encodeHttpError[E <: HttpError]: Encoder[E] = (error: E) =>
  Json.obj(
    ("msg", Json.fromString(error.msg)),
    ("cause", Json.fromString(error.cause))
  )

这样,您就拥有了用于HttpError的所有子类型以及用于HttpError的编码器实例。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65807131

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档