Skip to content

Commit 626f66f

Browse files
authored
Move ApolloParseException to ApolloNetworkException (apollographql#5816)
1 parent 01b135b commit 626f66f

File tree

8 files changed

+43
-27
lines changed

8 files changed

+43
-27
lines changed

libraries/apollo-api/api/apollo-api.api

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,10 @@ public final class com/apollographql/apollo3/exception/NoDataException : com/apo
13041304
public fun <init> (Ljava/lang/Throwable;)V
13051305
}
13061306

1307+
public final class com/apollographql/apollo3/exception/NullOrMissingField : com/apollographql/apollo3/exception/ApolloException {
1308+
public fun <init> (Ljava/lang/String;)V
1309+
}
1310+
13071311
public final class com/apollographql/apollo3/exception/RouterError : com/apollographql/apollo3/exception/ApolloException {
13081312
public fun <init> (Ljava/util/List;)V
13091313
public final fun getErrors ()Ljava/util/List;

libraries/apollo-api/src/commonMain/kotlin/com/apollographql/apollo3/api/Assertions.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
package com.apollographql.apollo3.api
55

66
import com.apollographql.apollo3.api.json.JsonReader
7-
import com.apollographql.apollo3.exception.DefaultApolloException
7+
import com.apollographql.apollo3.exception.NullOrMissingField
88
import kotlin.jvm.JvmMultifileClass
99
import kotlin.jvm.JvmName
1010

@@ -13,7 +13,7 @@ import kotlin.jvm.JvmName
1313
*/
1414
fun checkFieldNotMissing(value: Any?, name: String) {
1515
if (value == null) {
16-
throw DefaultApolloException("Field '$name' is missing or null")
16+
throw NullOrMissingField("Field '$name' is missing or null")
1717
}
1818
}
1919

@@ -35,5 +35,5 @@ fun assertOneOf(vararg args: Optional<*>) {
3535
* Helper function for the Kotlin codegen
3636
*/
3737
fun missingField(jsonReader: JsonReader, name: String): Nothing {
38-
throw DefaultApolloException("Field '$name' is missing or null at path ${jsonReader.getPath()}")
38+
throw NullOrMissingField("Field '$name' is missing or null at path ${jsonReader.getPath()}")
3939
}

libraries/apollo-api/src/commonMain/kotlin/com/apollographql/apollo3/api/Operations.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import com.apollographql.apollo3.api.json.JsonReader
88
import com.apollographql.apollo3.api.json.JsonWriter
99
import com.apollographql.apollo3.api.json.writeObject
1010
import com.apollographql.apollo3.exception.ApolloException
11-
import com.apollographql.apollo3.exception.ApolloParseException
11+
import com.apollographql.apollo3.exception.ApolloNetworkException
1212
import com.apollographql.apollo3.exception.JsonDataException
1313
import com.apollographql.apollo3.exception.JsonEncodingException
1414
import com.benasher44.uuid.Uuid
@@ -114,10 +114,9 @@ fun <D : Operation.Data> Operation<D>.parseResponse(
114114
val apolloException = if (throwable is ApolloException) {
115115
throwable
116116
} else {
117-
// This happens for null pointer exceptions on missing fields
118-
ApolloParseException(
119-
message = "Failed to parse GraphQL http network response",
120-
cause = throwable
117+
ApolloNetworkException(
118+
message = "Error while reading JSON response",
119+
platformCause = throwable
121120
)
122121
}
123122
return ApolloResponse.Builder(requestUuid = requestUuid ?: uuid4(), operation = this)

libraries/apollo-api/src/commonMain/kotlin/com/apollographql/apollo3/exception/Exceptions.kt

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import okio.BufferedSource
1515
sealed class ApolloException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause)
1616

1717
/**
18-
* A generic exception when no additional context exists
18+
* A generic exception used when there is no additional context besides the message.
1919
*/
2020
class DefaultApolloException(message: String? = null, cause: Throwable? = null): ApolloException(message, cause)
2121

@@ -25,7 +25,10 @@ class DefaultApolloException(message: String? = null, cause: Throwable? = null):
2525
class NoDataException(cause: Throwable?): ApolloException("No data was found", cause)
2626

2727
/**
28-
* A network error happened: socket closed, DNS issue, TLS problem, etc...
28+
* An I/O error happened: socket closed, DNS issue, TLS problem, file not found, etc...
29+
*
30+
* This is called [ApolloNetworkException] for historical reasons, but it should have been `ApolloIOException` instead.
31+
* [ApolloNetworkException] is thrown when an I/O error happens reading the operation.
2932
*
3033
* @param message a message indicating what the error was.
3134
* @param platformCause the underlying cause. Might be null. When not null, it can be cast to:
@@ -58,7 +61,6 @@ class SubscriptionConnectionException(
5861
val payload: Any?,
5962
) : ApolloException(message = "Subscription connection error")
6063

61-
6264
/**
6365
* The router sent one or several errors.
6466
*
@@ -108,15 +110,26 @@ class JsonEncodingException(message: String) : ApolloException(message)
108110
*
109111
* Exceptions of this type should be fixed by either changing the application code to accept the unexpected JSON, or by changing the JSON
110112
* to conform to the application's expectations.
111-
*
112-
* This exception may also be triggered if a document's nesting exceeds 31 levels. This depth is sufficient for all practical applications,
113-
* but shallow enough to avoid uglier failures like [StackOverflowError].
114113
*/
115114
class JsonDataException(message: String) : ApolloException(message)
116115

117116
/**
118-
* The response could not be parsed either because of another issue than [JsonDataException] or [JsonEncodingException]
117+
* A field was missing or null in the JSON response.
118+
*
119+
* Due to the way the parsers work, it is not possible to distinguish between both cases.
120+
*/
121+
class NullOrMissingField(message: String): ApolloException(message)
122+
123+
/**
124+
* The response could not be parsed because of an I/O exception.
125+
*
126+
* JSON and GraphQL errors are throwing other errors, see [JsonEncodingException], [JsonDataException] and [NullOrMissingField]
127+
*
128+
* @see JsonEncodingException
129+
* @see JsonDataException
130+
* @see NullOrMissingField
119131
*/
132+
@Deprecated("ApolloParseException was only used for I/O exceptions and is now mapped to ApolloNetworkException.")
120133
class ApolloParseException(message: String? = null, cause: Throwable? = null) : ApolloException(message = message, cause = cause)
121134

122135
class ApolloGraphQLException(val error: Error): ApolloException("GraphQL error: '${error.message}'") {

libraries/apollo-runtime-java/src/main/java/com/apollographql/apollo3/runtime/java/network/http/HttpNetworkTransport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public <D extends Operation.Data> void execute(@NotNull ApolloRequest<D> request
6969
}
7070

7171
@Override public void onFailure(@NotNull ApolloNetworkException exception) {
72-
callback.onResponse(getExceptionResponse(request, new ApolloParseException("Cannot parse response", exception)));
72+
callback.onResponse(getExceptionResponse(request, exception));
7373
}
7474
});
7575
}

libraries/apollo-runtime/src/commonMain/kotlin/com/apollographql/apollo3/network/http/HttpNetworkTransport.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import com.apollographql.apollo3.api.parseResponse
1818
import com.apollographql.apollo3.api.toApolloResponse
1919
import com.apollographql.apollo3.exception.ApolloException
2020
import com.apollographql.apollo3.exception.ApolloHttpException
21-
import com.apollographql.apollo3.exception.ApolloParseException
21+
import com.apollographql.apollo3.exception.ApolloNetworkException
2222
import com.apollographql.apollo3.exception.RouterError
2323
import com.apollographql.apollo3.internal.DeferredJsonMerger
2424
import com.apollographql.apollo3.internal.isMultipart
@@ -104,10 +104,9 @@ private constructor(
104104
val apolloException = if (throwable is ApolloException) {
105105
throwable
106106
} else {
107-
// This happens for null pointer exceptions on missing fields
108-
ApolloParseException(
109-
message = "Failed to parse GraphQL http network response",
110-
cause = throwable
107+
ApolloNetworkException(
108+
message = "Error while reading JSON response",
109+
platformCause = throwable
111110
)
112111
}
113112
return ApolloResponse.Builder(requestUuid = uuid4(), operation = operation)

tests/data-builders-kotlin/src/test/kotlin/test/FragmentTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package test
22

3-
import com.apollographql.apollo3.exception.DefaultApolloException
3+
import com.apollographql.apollo3.exception.NullOrMissingField
44
import data.builders.fragment.AnimalDetailsImpl
55
import data.builders.fragment.CatDetailsImpl
66
import data.builders.fragment.TrivialFragmentImpl
@@ -43,7 +43,7 @@ class FragmentTest {
4343
// __typename is unknown so this fails
4444
// XXX: we could be smarter about this (the parsers are
4545
// data.builders.fragment.AnimalDetailsImpl_ResponseAdapter$OnAnimal.fromJson(AnimalDetailsImpl_ResponseAdapter.kt:85)
46-
assertFailsWith(DefaultApolloException::class) {
46+
assertFailsWith(NullOrMissingField::class) {
4747
TrivialFragmentImpl.Data(Animal) {
4848
__typename = "Brontaroc"
4949
species = "alien"

tests/http-cache/src/test/kotlin/HttpCacheTest.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
12
import com.apollographql.apollo3.ApolloClient
23
import com.apollographql.apollo3.cache.http.HttpFetchPolicy
34
import com.apollographql.apollo3.cache.http.httpCache
45
import com.apollographql.apollo3.cache.http.httpExpireTimeout
56
import com.apollographql.apollo3.cache.http.httpFetchPolicy
67
import com.apollographql.apollo3.cache.http.isFromHttpCache
7-
import com.apollographql.apollo3.exception.ApolloParseException
8+
import com.apollographql.apollo3.exception.ApolloNetworkException
89
import com.apollographql.apollo3.exception.HttpCacheMissException
910
import com.apollographql.apollo3.mockserver.MockServer
1011
import com.apollographql.apollo3.mockserver.awaitRequest
@@ -212,9 +213,9 @@ class HttpCacheTest {
212213
@Test
213214
fun incompleteJsonIsNotCached() = runTest(before = { before() }, after = { tearDown() }) {
214215
mockServer.enqueueString("""{"data":""")
215-
assertIs<ApolloParseException>(
216-
apolloClient.query(GetRandomQuery()).execute().exception
217-
)
216+
apolloClient.query(GetRandomQuery()).execute().exception.apply {
217+
assertIs<ApolloNetworkException>(this)
218+
}
218219
// Should not have been cached
219220
assertIs<HttpCacheMissException>(
220221
apolloClient.query(GetRandomQuery()).httpFetchPolicy(HttpFetchPolicy.CacheOnly).execute().exception

0 commit comments

Comments
 (0)