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
编码为 circe
和 http4s
?我试过这样做:
implicit def encoderHttpThrowable: EntityEncoder[Env, Throwable] = jsonEncoderOf[Env, Throwable]
但是没有解决问题
无法使用 Circe(或任何其他库)自动编码 Java 层次结构(我很确定这一点)。
所以你有 3 种可能性:
只需使用错误消息:
case GET -> Root / "things" =>
things.all.foldM (
error => InternalServerError(error.getMessage()),
Ok(_)
)
或者去掉 Throwable:
sealed trait MyError
final case class SecondError(msg: String) extends MyError
现在您可以对错误进行编码
...
case GET -> Root / "things" =>
things.all.foldM (
error => InternalServerError(error),
Ok(_)
)
将您的 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(_)
)
我创建了错误层次结构:
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
编码为 circe
和 http4s
?我试过这样做:
implicit def encoderHttpThrowable: EntityEncoder[Env, Throwable] = jsonEncoderOf[Env, Throwable]
但是没有解决问题
无法使用 Circe(或任何其他库)自动编码 Java 层次结构(我很确定这一点)。
所以你有 3 种可能性:
只需使用错误消息:
case GET -> Root / "things" => things.all.foldM ( error => InternalServerError(error.getMessage()), Ok(_) )
或者去掉 Throwable:
sealed trait MyError final case class SecondError(msg: String) extends MyError
现在您可以对错误进行编码
... case GET -> Root / "things" => things.all.foldM ( error => InternalServerError(error), Ok(_) )
将您的 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(_) )