private def decodeJson[A : Decoder]()

in payment-failure/src/main/scala/com/gu/identity/paymentfailure/IdentityClient.scala [18:38]


  private def decodeJson[A : Decoder](body: String): Either[IdentityClientError, A] =
    decode[A](body).leftMap(err => IdentityClientError.fromCirceError(body, err))

  private def decodeApiError(body: String): IdentityClientError =
    decodeJson[ApiError](body).merge

  private def executePostRequest[Req: Encoder, Res: Decoder](path: String, requestBody: Req): Either[IdentityClientError, Res] = {
    logger.info(s"executing POST $path")

    val request = Http(s"${config.idapiHost}$path")
      .postData(requestBody.asJson.noSpaces)
      .header("X-GU-ID-Client-Access-Token", s"Bearer ${config.idapiAccessToken}")
      .header("content-type", "application/json")

    Either.catchNonFatal(request.asString)
      .leftMap(err => IdentityClientError.fromThrowable(err))
      .flatMap {
        case res if res.is2xx => decodeJson[Res](res.body)
        case res => Left(decodeApiError(res.body))
      }
  }