Scala、Circe、Http4s——在 Circe 中编码 Throwable 有什么方法吗?

Scala, Circe, Http4s - is it any way to encode Throwable in Circe?

我创建了错误层次结构:

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]

是否可以将 Throwable 编码为 circehttp4s?我试过这样做:

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

但是没有解决问题

无法使用 Circe(或任何其他库)自动编码 Java 层次结构(我很确定这一点)。

所以你有 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(_)
      )