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

caliban.client.GraphQLResponseError.scala Maven / Gradle / Ivy

The newest version!
package caliban.client

import caliban.client.GraphQLResponseError.Location
import com.github.plokhotnyuk.jsoniter_scala.core.{ JsonReader, JsonValueCodec, JsonWriter }
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker

import scala.annotation.switch

/**
 * An GraphQL error as returned by the server.
 * @param message error message
 * @param locations line and column that caused the error in the initial query
 * @param path path of the field that caused the error
 */
case class GraphQLResponseError(
  message: String,
  locations: Option[List[Location]],
  path: Option[List[Either[String, Int]]],
  extensions: Option[__Value]
) {

  /**
   * Renders the error as a string
   * @param includeExtensions whether to include the extensions in the error message
   * @return the error message
   */
  def render(includeExtensions: Boolean): String =
    s"${message} ${locations.getOrElse(Nil).map(loc => s"at line ${loc.line} and column ${loc.column}").mkString(" ")}${path.fold("")(p =>
        s" at path ${p.map {
            case Left(value)  => s"/$value"
            case Right(value) => s"[$value]"
          }.mkString("")}"
      )}${if (includeExtensions) extensions.fold("")(ext => s" Extensions: $ext") else ""}"
}

object GraphQLResponseError {

  case class Location(line: Int, column: Int)

  private implicit val eitherCodec: JsonValueCodec[Either[String, Int]] = new JsonValueCodec[Either[String, Int]] {
    override def decodeValue(in: JsonReader, default: Either[String, Int]): Either[String, Int] = {
      val b = in.nextToken()
      in.rollbackToken()
      (b: @switch) match {
        case '"'                                                             => Left(in.readString(null))
        case '-' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => Right(in.readInt())
        case _                                                               => in.decodeError("expected int or string")
      }
    }

    override def encodeValue(x: Either[String, Int], out: JsonWriter): Unit =
      x.fold(out.writeVal, out.writeVal)

    override def nullValue: Either[String, Int] =
      null.asInstanceOf[Either[String, Int]]
  }

  implicit val locationCodec: JsonValueCodec[Location] = JsonCodecMaker.makeCirceLike[Location]

  implicit val jsonCodec: JsonValueCodec[GraphQLResponseError] = JsonCodecMaker.makeCirceLike[GraphQLResponseError]

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy