All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sttp.client3.EitherBackend.scala Maven / Gradle / Ivy

The newest version!
package sttp.client3

import sttp.capabilities.Effect
import sttp.client3.monad.{FunctionK, MapEffect}
import sttp.monad.{EitherMonad, MonadError}

import scala.util.control.NonFatal

/** A synchronous backend that safely wraps [[SttpBackend]] exceptions in `Either[Throwable, *]`'s
  *
  * @param delegate
  *   A synchronous `SttpBackend` which to which this backend forwards all requests
  * @tparam P
  *   TODO
  */
class EitherBackend[P](delegate: SttpBackend[Identity, P]) extends SttpBackend[Either[Throwable, *], P] {
  override def send[T, R >: P with Effect[Either[Throwable, *]]](
      request: Request[T, R]
  ): Either[Throwable, Response[T]] =
    doTry(
      delegate.send(
        MapEffect[Either[Throwable, *], Identity, Identity, T, P](
          request: Request[T, P with Effect[Either[Throwable, *]]],
          eitherToId,
          idToEither,
          responseMonad,
          delegate.responseMonad
        )
      )
    )

  override def close(): Either[Throwable, Unit] = doTry(delegate.close())

  private def doTry[T](t: => T): Either[Throwable, T] = {
    try Right(t)
    catch {
      case NonFatal(e) => Left(e)
    }
  }

  override def responseMonad: MonadError[Either[Throwable, *]] = EitherMonad

  private val eitherToId: FunctionK[Either[Throwable, *], Identity] =
    new FunctionK[Either[Throwable, *], Identity] {
      override def apply[A](fa: Either[Throwable, A]): Identity[A] =
        fa match {
          case Left(e)  => throw e
          case Right(v) => v
        }
    }

  private val idToEither: FunctionK[Identity, Either[Throwable, *]] =
    new FunctionK[Identity, Either[Throwable, *]] {
      override def apply[A](fa: Identity[A]): Either[Throwable, A] = Right(fa)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy