1

I am trying to use Blaze client for http4s to make http calls. It works fine when 200 response is returned but in case of HTTP 500 or 400 I am not able to figure out how to retrieve the detailed error message returned from server.

I am can only see folllwing in the logs for this client.

2022-11-10 23:37:40 INFO - Shutting down connection pool: curAllocated=1 idleQueues.size=1 waitQueue.size=0 maxWaitQueueLimit=256 closed=false org.http4s.client.UnexpectedStatus: unexpected HTTP status: 500 Internal Server Error

  def callEffect(client: Client[IO]): IO[String] = {
    val uri = serverUrl
      .withPath("/abc")
    val request = GET(uri, Accept(MediaType.application.json))

    client.expect[String](request).map { res =>
      println(res)
      res
    }
  }

  def deploy(implicit cs: ContextShift[IO]): IO[ExitCode] = {
    BlazeClientBuilder[IO](scala.concurrent.ExecutionContext.global).resource
      .map(x => println(callEffect(x).unsafeRunSync()))
      .use(_ => IO.unit.as(ExitCode.Success))
  }
Amit Kumar
  • 2,685
  • 2
  • 37
  • 72

1 Answers1

1

Since the result is provided inside an IO, you can use any of IO's error handling features to handle the issues, for example with redeem

def run(args: List[String]): IO[ExitCode] = {
    BlazeClientBuilder[IO].resource
      .use(client =>
        for {
          result <- callEffect(client).redeem(
            error => "could not get a result",
            something => s"this is what I got: $something"
          )
          _ <- IO.println(result)
        } yield ExitCode.Success
      )
  }

There's a great article on this topic here: https://softwaremill.com/practical-guide-to-error-handling-in-scala-cats-and-cats-effect/

For even more control, you can handle errors from the client itself, for example using expectOr() instead of expect(), which gives you access to a convenient onError: Response[F] => F[Throwable].

Svend
  • 6,352
  • 1
  • 25
  • 38