【问题标题】:Scala, Circe, Http4s - is it any way to encode Throwable in Circe?Scala,Circe,Http4s - 有什么方法可以在 Circe 中编码 Throwable?
【发布时间】:2020-05-03 10:15:24
【问题描述】:

我创建了错误层次结构:

sealed trait MyError extends Throwable
final case class SecondError(msg: String) extends MyError

现在我的http4s 路由中可能会出现这种错误:

case GET -> Root / "things" => for {
        response <- things.all.foldM(
          error => error match {
            case SecondError(_) => InternalServerError(error)            
          }
...

但我得到编译错误:

could not find implicit value for parameter encoder: io.circe.Encoder[Throwable]

是否可以用circehttp4sThrowable 进行编码?我试着这样做:

implicit def encoderHttpThrowable: EntityEncoder[Env, Throwable] = jsonEncoderOf[Env, Throwable]

但这并没有解决问题。

【问题讨论】:

  • 根据记忆,您没有 MyError 特征扩展 Throwable,而是将 Throwable 匹配到您的 MyErrors 之一。然后你只需要对错误的案例类进行编码
  • 您的意思是扩展 Error 而不是 Throwable?如果我使用的函数需要 Throwable 签名怎么办?
  • 在“世界末日”,你有一个Throwable =&gt; MyError 的函数,然后circe 对其结果进行编码
  • 这里有一篇文章处理这个问题:typelevel.org/blog/2018/08/25/http4s-error-handling-mtl.html
  • 我有自定义错误的编码器。问题仅在于 Throwable

标签: json scala circe http4s zio


【解决方案1】:

不可能使用 Circe(或任何其他库)自动编码 Java Hierarchy(我很确定)。

所以你有 3 种可能性:

  1. 只需使用错误消息:

    case GET -> Root / "things"  =>
        things.all.foldM (
          error => InternalServerError(error.getMessage()),
          Ok(_)
        )
    
  2. 或者摆脱 Throwable:

      sealed trait MyError
      final case class SecondError(msg: String) extends MyError
    

    现在您可以对错误进行编码

    ...
    case GET -> Root / "things"  =>
      things.all.foldM (
        error => InternalServerError(error),
        Ok(_)
      )
    
  3. 将您的 Throwable 映射到您自己的错误(没有 Throwable 的密封特征):

    ...
    case GET -> Root / "things"  =>
      things.all
        .mapError{
          case ex: IllegalArgumentException => SecondError(ex.getMessage)
          case ex => FirstError(ex.getMessage)
       }
        .foldM (
        error => InternalServerError(error),
        Ok(_)
      )
    

【讨论】:

  • 这里的问题是我的函数things.all返回ZIO[Any, Throwable, Data],所以第二种方案是不能用的。我会尝试第一个。
  • 还有另一种可能性;)检查我的答案
  • 谢谢,我做了一些魔术,还从扩展中删除了 Throwable 并且它可以工作。
猜你喜欢
  • 2021-04-24
  • 2017-06-12
  • 2020-07-20
  • 2020-07-06
  • 2019-03-13
  • 2017-07-10
  • 2021-09-21
  • 2023-03-12
  • 2020-09-26
相关资源
最近更新 更多