Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 46 additions & 1 deletion libraries/apollo-api/api/apollo-api.api
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public final class com/apollographql/apollo3/api/Adapters {
public static final fun -obj (Lcom/apollographql/apollo3/api/Adapter;)Lcom/apollographql/apollo3/api/ObjectAdapter;
public static final fun -optional (Lcom/apollographql/apollo3/api/Adapter;)Lcom/apollographql/apollo3/api/PresentAdapter;
public static final fun -present (Lcom/apollographql/apollo3/api/Adapter;)Lcom/apollographql/apollo3/api/PresentAdapter;
public static final fun -result (Lcom/apollographql/apollo3/api/Adapter;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)Lcom/apollographql/apollo3/api/ResultAdapter;
public static final fun -toJson (Lcom/apollographql/apollo3/api/Adapter;Ljava/lang/Object;)Ljava/lang/String;
public static final fun -toJson (Lcom/apollographql/apollo3/api/Adapter;Ljava/lang/Object;Lcom/apollographql/apollo3/api/CustomScalarAdapters;)Ljava/lang/String;
public static final fun -toJson (Lcom/apollographql/apollo3/api/Adapter;Ljava/lang/Object;Lcom/apollographql/apollo3/api/CustomScalarAdapters;Ljava/lang/String;)Ljava/lang/String;
Expand Down Expand Up @@ -397,14 +398,15 @@ public final class com/apollographql/apollo3/api/CompositeAdapterContext {
public final field customScalarAdapters Lcom/apollographql/apollo3/api/CustomScalarAdapters;
public final field deferredFragmentIdentifiers Ljava/util/Set;
public final field falseVariables Ljava/util/Set;
public synthetic fun <init> (Lcom/apollographql/apollo3/api/CustomScalarAdapters;Ljava/util/Set;Ljava/util/Set;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public synthetic fun <init> (Lcom/apollographql/apollo3/api/CustomScalarAdapters;Ljava/util/Set;Ljava/util/Set;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
}

public final class com/apollographql/apollo3/api/CompositeAdapterContext$Builder {
public fun <init> ()V
public final fun build ()Lcom/apollographql/apollo3/api/CompositeAdapterContext;
public final fun customScalarAdapters (Lcom/apollographql/apollo3/api/CustomScalarAdapters;)Lcom/apollographql/apollo3/api/CompositeAdapterContext$Builder;
public final fun deferredFragmentIdentifiers (Ljava/util/Set;)Lcom/apollographql/apollo3/api/CompositeAdapterContext$Builder;
public final fun errors (Ljava/util/List;)Lcom/apollographql/apollo3/api/CompositeAdapterContext$Builder;
public final fun falseVariables (Ljava/util/Set;)Lcom/apollographql/apollo3/api/CompositeAdapterContext$Builder;
}

Expand All @@ -419,6 +421,7 @@ public final class com/apollographql/apollo3/api/CompositeAdaptersKt {
public static final fun -obj (Lcom/apollographql/apollo3/api/CompositeAdapter;Z)Lcom/apollographql/apollo3/api/ObjectCompositeAdapter;
public static synthetic fun -obj$default (Lcom/apollographql/apollo3/api/CompositeAdapter;ZILjava/lang/Object;)Lcom/apollographql/apollo3/api/ObjectCompositeAdapter;
public static final fun -present (Lcom/apollographql/apollo3/api/CompositeAdapter;)Lcom/apollographql/apollo3/api/PresentCompositeAdapter;
public static final fun -result (Lcom/apollographql/apollo3/api/CompositeAdapter;)Lcom/apollographql/apollo3/api/ResultCompositeAdapter;
public static final fun -toJson (Lcom/apollographql/apollo3/api/CompositeAdapter;Ljava/lang/Object;)Ljava/lang/String;
public static final fun -toJson (Lcom/apollographql/apollo3/api/CompositeAdapter;Ljava/lang/Object;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)Ljava/lang/String;
public static final fun -toJson (Lcom/apollographql/apollo3/api/CompositeAdapter;Ljava/lang/Object;Lcom/apollographql/apollo3/api/CompositeAdapterContext;Ljava/lang/String;)Ljava/lang/String;
Expand Down Expand Up @@ -884,6 +887,44 @@ public abstract interface class com/apollographql/apollo3/api/Query : com/apollo
public abstract interface class com/apollographql/apollo3/api/Query$Data : com/apollographql/apollo3/api/Operation$Data {
}

public abstract interface class com/apollographql/apollo3/api/Result {
public fun errorsOrNull ()Ljava/util/List;
public fun getOrNull ()Ljava/lang/Object;
public fun getOrThrow ()Ljava/lang/Object;
}

public final class com/apollographql/apollo3/api/Result$Data : com/apollographql/apollo3/api/Result {
public fun <init> (Ljava/lang/Object;)V
public final fun getValue ()Ljava/lang/Object;
}

public final class com/apollographql/apollo3/api/Result$Error : com/apollographql/apollo3/api/Result {
public fun <init> (Ljava/util/List;)V
public final fun getErrors ()Ljava/util/List;
}

public final class com/apollographql/apollo3/api/ResultAdapter : com/apollographql/apollo3/api/Adapter {
public fun <init> (Lcom/apollographql/apollo3/api/Adapter;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)V
public fun fromJson (Lcom/apollographql/apollo3/api/json/JsonReader;Lcom/apollographql/apollo3/api/CustomScalarAdapters;)Lcom/apollographql/apollo3/api/Result;
public synthetic fun fromJson (Lcom/apollographql/apollo3/api/json/JsonReader;Lcom/apollographql/apollo3/api/CustomScalarAdapters;)Ljava/lang/Object;
public fun toJson (Lcom/apollographql/apollo3/api/json/JsonWriter;Lcom/apollographql/apollo3/api/CustomScalarAdapters;Lcom/apollographql/apollo3/api/Result;)V
public synthetic fun toJson (Lcom/apollographql/apollo3/api/json/JsonWriter;Lcom/apollographql/apollo3/api/CustomScalarAdapters;Ljava/lang/Object;)V
}

public final class com/apollographql/apollo3/api/ResultCompositeAdapter : com/apollographql/apollo3/api/CompositeAdapter {
public fun <init> (Lcom/apollographql/apollo3/api/CompositeAdapter;)V
public fun fromJson (Lcom/apollographql/apollo3/api/json/JsonReader;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)Lcom/apollographql/apollo3/api/Result;
public synthetic fun fromJson (Lcom/apollographql/apollo3/api/json/JsonReader;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)Ljava/lang/Object;
public fun toJson (Lcom/apollographql/apollo3/api/json/JsonWriter;Lcom/apollographql/apollo3/api/Result;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)V
public synthetic fun toJson (Lcom/apollographql/apollo3/api/json/JsonWriter;Ljava/lang/Object;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)V
}

public final class com/apollographql/apollo3/api/ResultKt {
public static final fun getOrElse (Lcom/apollographql/apollo3/api/Result;Ljava/lang/Object;)Ljava/lang/Object;
public static final fun missingField (Lcom/apollographql/apollo3/api/json/JsonReader;Ljava/lang/String;)Ljava/lang/Object;
public static final fun missingFieldResult (Lcom/apollographql/apollo3/api/json/JsonReader;Lcom/apollographql/apollo3/api/CompositeAdapterContext;)Lcom/apollographql/apollo3/api/Result;
}

public final class com/apollographql/apollo3/api/ScalarType : com/apollographql/apollo3/api/CompiledNamedType {
public fun <init> (Ljava/lang/String;)V
}
Expand Down Expand Up @@ -1314,6 +1355,10 @@ public final class com/apollographql/apollo3/exception/MissingValueException : c
public fun <init> ()V
}

public final class com/apollographql/apollo3/exception/NoDataAndNoErrorsException : com/apollographql/apollo3/exception/ApolloException {
public fun <init> (Ljava/lang/Throwable;)V
}

public final class com/apollographql/apollo3/exception/NoDataException : com/apollographql/apollo3/exception/ApolloException {
public fun <init> (Ljava/lang/Throwable;)V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ class NullableAdapter<T : Any>(private val wrappedAdapter: Adapter<T>) : Adapter
}
}

class ResultAdapter<T : Any>(private val wrappedAdapter: Adapter<T>, private val adapterContext: CompositeAdapterContext) : Adapter<Result<T>> {
override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): Result<T> {
if (reader.peek() == JsonReader.Token.NULL) {
val errors = adapterContext.errorsForPath(reader.getPath())
if (errors.isNotEmpty()) {
reader.skipValue()
return Result.Error(errors)
}
}
return Result.Data(wrappedAdapter.fromJson(reader, customScalarAdapters))
}

override fun toJson(writer: JsonWriter, customScalarAdapters: CustomScalarAdapters, value: Result<T>) {
// We do not support serializing errors
wrappedAdapter.toJson(writer, customScalarAdapters, value.getOrThrow())
}
}


@Deprecated("Use PresentAdapter instead")
class OptionalAdapter<T>(private val wrappedAdapter: Adapter<T>) : Adapter<Optional.Present<@JvmSuppressWildcards T>> {
override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): Optional.Present<T> {
Expand Down Expand Up @@ -121,7 +140,7 @@ class ApolloOptionalAdapter<T>(private val wrappedAdapter: Adapter<T>) : Adapter
@JvmName("-obj")
fun <T> Adapter<T>.obj() = ObjectAdapter(this)

class ObjectAdapter<T>(private val wrappedAdapter: Adapter<T>): Adapter<T> {
class ObjectAdapter<T>(private val wrappedAdapter: Adapter<T>) : Adapter<T> {
override fun fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): T {
throw IllegalStateException("Input type used in output position")
}
Expand Down Expand Up @@ -302,6 +321,9 @@ fun <T : Any> Adapter<T>.nullable() = NullableAdapter(this)
@JvmName("-list")
fun <T> Adapter<T>.list() = ListAdapter(this)

@JvmName("-result")
fun <T : Any> Adapter<T>.result(adapterContext: CompositeAdapterContext) = ResultAdapter(this, adapterContext)

/**
* Note that Arrays require their type to be known at compile time, so we construct an anonymous object with reference to
* function with reified type parameters as a workaround.
Expand All @@ -310,7 +332,11 @@ fun <T> Adapter<T>.list() = ListAdapter(this)
@JvmName("-array")
inline fun <reified T> Adapter<T>.array() = object : Adapter<Array<T>> {

private inline fun <reified T> arrayFromJson(wrappedAdapter: Adapter<T>, reader: JsonReader, customScalarAdapters: CustomScalarAdapters): Array<T> {
private inline fun <reified T> arrayFromJson(
wrappedAdapter: Adapter<T>,
reader: JsonReader,
customScalarAdapters: CustomScalarAdapters,
): Array<T> {
reader.beginArray()
val list = mutableListOf<T>()
while (reader.hasNext()) {
Expand All @@ -324,7 +350,7 @@ inline fun <reified T> Adapter<T>.array() = object : Adapter<Array<T>> {
wrappedAdapter: Adapter<T>,
writer: JsonWriter,
customScalarAdapters: CustomScalarAdapters,
value: Array<T>
value: Array<T>,
) {
writer.beginArray()
value.forEach {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.apollographql.apollo3.api
import com.apollographql.apollo3.exception.ApolloException
import com.apollographql.apollo3.exception.ApolloGraphQLException
import com.apollographql.apollo3.exception.DefaultApolloException
import com.apollographql.apollo3.exception.NoDataAndNoErrorsException
import com.apollographql.apollo3.exception.NoDataException
import com.benasher44.uuid.Uuid
import kotlin.jvm.JvmField
Expand Down Expand Up @@ -80,8 +81,7 @@ private constructor(
) {

/**
* An [ApolloException] if a complete GraphQL response wasn't received, an instance of [ApolloGraphQLException] if GraphQL
* errors were return or another instance of [ApolloException] if a network, parsing, caching or other error happened.
* An [ApolloException] if a network, parsing, caching or other error happened.
*
* For example, `exception` is non-null if there is a network failure or cache miss.
*
Expand All @@ -90,8 +90,7 @@ private constructor(
@JvmField
val exception: ApolloException? = when {
exception != null -> exception
!errors.isNullOrEmpty() -> ApolloGraphQLException(errors)
data == null -> DefaultApolloException("No data and no error was returned")
data == null -> NoDataAndNoErrorsException(exception)
else -> null
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.apollographql.apollo3.api

import com.apollographql.apollo3.annotations.ApolloExperimental
import com.apollographql.apollo3.api.json.JsonReader
import com.apollographql.apollo3.api.json.JsonWriter
import okio.IOException
Expand Down Expand Up @@ -32,11 +33,19 @@ class CompositeAdapterContext private constructor(

@JvmField
val deferredFragmentIdentifiers: Set<DeferredFragmentIdentifier>?,

private var errors: List<Error>,
) {


@ApolloExperimental
fun errorsForPath(path: List<Any>) = errorsForPath(path, errors)

class Builder {
private var customScalarAdapters: CustomScalarAdapters? = null
private var falseVariables: Set<String>? = null
private var deferredFragmentIdentifiers: Set<DeferredFragmentIdentifier>? = null
private var errors: List<Error>? = null

fun customScalarAdapters(customScalarAdapters: CustomScalarAdapters) = apply {
this.customScalarAdapters = customScalarAdapters
Expand All @@ -45,15 +54,21 @@ class CompositeAdapterContext private constructor(
fun falseVariables(falseVariables: Set<String>?) = apply {
this.falseVariables = falseVariables
}

fun deferredFragmentIdentifiers(deferredFragmentIdentifiers: Set<DeferredFragmentIdentifier>?) = apply {
this.deferredFragmentIdentifiers = deferredFragmentIdentifiers
}

fun errors(errors: List<Error>) = apply {
this.errors = errors
}

fun build(): CompositeAdapterContext {
return CompositeAdapterContext(
customScalarAdapters ?: CustomScalarAdapters.Empty,
falseVariables ?: emptySet(),
deferredFragmentIdentifiers
deferredFragmentIdentifiers,
errors ?: emptyList()
)
}

Expand All @@ -67,3 +82,22 @@ fun <T> CompositeAdapter<T>.toJson(writer: JsonWriter, customScalarAdapters: Cus
fun <T> CompositeAdapter<T>.fromJson(reader: JsonReader, customScalarAdapters: CustomScalarAdapters): T {
return fromJson(reader, CompositeAdapterContext.Builder().customScalarAdapters(customScalarAdapters).build())
}

private fun List<Any>.startsWith(responsePath: List<Any>): Boolean {
for (i in 1.until(responsePath.size)) {
if (i - 1 >= this.size) {
return false
}
if (responsePath[i] != this[i - 1]) {
return false
}
}
return true
}

private fun errorsForPath(responsePath: List<Any>, errors: List<Error>): List<Error> {
// XXX: optimize
return errors.filter {
it.path?.startsWith(responsePath) ?: false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.apollographql.apollo3.api.json.MapJsonReader.Companion.buffer
import com.apollographql.apollo3.api.json.MapJsonWriter
import com.apollographql.apollo3.api.json.buildJsonString
import com.apollographql.apollo3.api.json.writeAny
import com.apollographql.apollo3.exception.DefaultApolloException
import kotlin.jvm.JvmName
import kotlin.jvm.JvmOverloads
import kotlin.jvm.JvmSuppressWildcards
Expand Down Expand Up @@ -55,6 +56,27 @@ class NullableCompositeAdapter<T : Any>(private val wrappedAdapter: CompositeAda
}
}

class ResultCompositeAdapter<T : Any>(private val wrappedAdapter: CompositeAdapter<T>): CompositeAdapter<Result<T>> {
override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): Result<T> {
try {
return Result.Data(wrappedAdapter.fromJson(reader, adapterContext))
} catch (e: Exception) {
val errors = adapterContext.errorsForPath(reader.getPath())
if (errors.isNotEmpty()) {
reader.skipValue()
return Result.Error(errors)
}

throw DefaultApolloException("no error found for @catch field at '${reader.getPath()}'")
}
}

override fun toJson(writer: JsonWriter, value: Result<T>, adapterContext: CompositeAdapterContext) {
// We do not support serializing errors
wrappedAdapter.toJson(writer, value.getOrThrow(), adapterContext)
}
}

class PresentCompositeAdapter<T>(private val wrappedAdapter: CompositeAdapter<T>) : CompositeAdapter<Optional.Present<@JvmSuppressWildcards T>> {
override fun fromJson(reader: JsonReader, adapterContext: CompositeAdapterContext): Optional.Present<T> {
return Optional.Present(wrappedAdapter.fromJson(reader, adapterContext))
Expand Down Expand Up @@ -132,6 +154,9 @@ class ObjectCompositeAdapter<T>(
}
}

@JvmName("-result")
fun <T : Any> CompositeAdapter<T>.result() = ResultCompositeAdapter(this)

@JvmName("-nullable")
fun <T : Any> CompositeAdapter<T>.nullable() = NullableCompositeAdapter(this)

Expand All @@ -145,6 +170,7 @@ fun <T> CompositeAdapter<T>.obj(buffered: Boolean = false) = ObjectCompositeAdap
fun <T> CompositeAdapter<T>.present() = PresentCompositeAdapter(this)



@JvmName("-toJson")
@JvmOverloads
fun <T> CompositeAdapter<T>.toJsonString(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,33 @@ fun <D : Executable.Data> Executable<D>.parseData(
customScalarAdapters: CustomScalarAdapters = CustomScalarAdapters.Empty,
falseVariables: Set<String>? = null,
deferredFragmentIds: Set<DeferredFragmentIdentifier>? = null,
): D? {
return parseData(
jsonReader = jsonReader,
customScalarAdapters = customScalarAdapters,
falseVariables = falseVariables,
deferredFragmentIds = deferredFragmentIds,
errors = emptyList()
)
}

@ApolloInternal
fun <D : Executable.Data> Executable<D>.parseData(
jsonReader: JsonReader,
customScalarAdapters: CustomScalarAdapters,
falseVariables: Set<String>?,
deferredFragmentIds: Set<DeferredFragmentIdentifier>?,
errors: List<Error>,
): D? {
val adapterContext = CompositeAdapterContext.Builder()
.customScalarAdapters(customScalarAdapters)
.falseVariables(falseVariables)
.deferredFragmentIdentifiers(deferredFragmentIds)
.errors(errors)
.build()
return adapter().nullable().fromJson(jsonReader, adapterContext)
}


fun <D : Executable.Data> Executable<D>.composeData(
jsonWriter: JsonWriter,
customScalarAdapters: CustomScalarAdapters,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.apollographql.apollo3.api

import com.apollographql.apollo3.api.json.JsonReader
import com.apollographql.apollo3.exception.ApolloGraphQLException
import com.apollographql.apollo3.exception.DefaultApolloException

sealed interface Result<out V> {
fun getOrNull(): V? = (this as? Data)?.value
fun getOrThrow(): V {
return when(this) {
is Data -> value
is Error -> throw ApolloGraphQLException(errors)
}
}

fun errorsOrNull(): List<com.apollographql.apollo3.api.Error>? = (this as? Error)?.errors

class Data<V>(val value: V): Result<V>
class Error(val errors: List<com.apollographql.apollo3.api.Error>) : Result<Nothing>
}


fun <V> Result<V>.getOrElse(fallback: V): V = (this as? Result.Data)?.value ?: fallback

fun <V> missingFieldResult(jsonReader: JsonReader, adapterContext: CompositeAdapterContext): Result<V> {
val errors = adapterContext.errorsForPath(jsonReader.getPath())
if (errors.isEmpty()) {
throw DefaultApolloException("No field returned at ${jsonReader.getPath()}")
}

return Result.Error(errors)
}

fun <V> missingField(jsonReader: JsonReader, name: String): V {
throw DefaultApolloException("Field '$name' is missing at path ${jsonReader.getPath()}")
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal object ResponseParser {
when (jsonReader.nextName()) {
"data" -> {
val falseVariables = operation.falseVariables(customScalarAdapters)
data = operation.parseData(jsonReader, customScalarAdapters, falseVariables, deferredFragmentIds)
data = operation.parseData(jsonReader, customScalarAdapters, falseVariables, deferredFragmentIds, errors ?: emptyList())
}
"errors" -> errors = jsonReader.readErrors()
"extensions" -> extensions = jsonReader.readAny() as? Map<String, Any?>
Expand Down
Loading