Developus
Developus

Reputation: 1462

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

I have created hierarchy of errors:

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

Now I could get this kind of error in my http4s routes:

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

But I get compiled error:

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

Is it possible to encode Throwable with circe and http4s? I tried to do it this way:

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

But it did not solve a problem.

Upvotes: 2

Views: 764

Answers (1)

pme
pme

Reputation: 14803

It is not possible to encode automatically a Java Hierarchy with Circe (or any other library) (I am pretty sure of this).

So you have 3 possibilities:

  1. Just use the Message of the error:

    case GET -> Root / "things"  =>
        things.all.foldM (
          error => InternalServerError(error.getMessage()),
          Ok(_)
        )
    
  2. Or get rid of the Throwable:

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

    And now you can encode the error

    ...
    case GET -> Root / "things"  =>
      things.all.foldM (
        error => InternalServerError(error),
        Ok(_)
      )
    
  3. Map your Throwable to your own Error (Sealed Trait without Throwable):

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

Upvotes: 1

Related Questions