Skip to content

Commit

Permalink
Fix partial data throwing with useV3ExceptionHandling and normalized …
Browse files Browse the repository at this point in the history
…cache (#5313)
  • Loading branch information
BoD committed Oct 19, 2023
1 parent 62f367b commit 00cc6ad
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.apollographql.apollo3.api.ApolloResponse
import com.apollographql.apollo3.api.Operation
import com.apollographql.apollo3.api.Query
import com.apollographql.apollo3.exception.ApolloException
import com.apollographql.apollo3.exception.ApolloGraphQLException
import com.apollographql.apollo3.exception.CacheMissException
import com.apollographql.apollo3.exception.DefaultApolloException
import com.apollographql.apollo3.interceptor.ApolloInterceptor
Expand Down Expand Up @@ -143,7 +144,7 @@ internal val FetchPolicyRouterInterceptor = object : ApolloInterceptor {

request.fetchPolicyInterceptor.intercept(request, chain)
.collect {
if (!hasEmitted && it.exception != null) {
if (!hasEmitted && it.exception != null && it.exception !is ApolloGraphQLException) {
// Remember to send the exception later
exceptions.add(it.exception!!)
return@collect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.apollographql.apollo3.api.ApolloResponse
import com.apollographql.apollo3.api.Operation
import com.apollographql.apollo3.api.Query
import com.apollographql.apollo3.exception.ApolloException
import com.apollographql.apollo3.exception.ApolloGraphQLException
import com.apollographql.apollo3.exception.CacheMissException
import com.apollographql.apollo3.exception.DefaultApolloException
import com.apollographql.apollo3.interceptor.ApolloInterceptor
Expand Down Expand Up @@ -143,7 +144,7 @@ internal val FetchPolicyRouterInterceptor = object : ApolloInterceptor {

request.fetchPolicyInterceptor.intercept(request, chain)
.collect {
if (!hasEmitted && it.exception != null) {
if (!hasEmitted && it.exception != null && it.exception !is ApolloGraphQLException) {
// Remember to send the exception later
exceptions.add(it.exception!!)
return@collect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package test

import com.apollographql.apollo3.ApolloClient
import com.apollographql.apollo3.cache.normalized.api.MemoryCacheFactory
import com.apollographql.apollo3.cache.normalized.normalizedCache
import com.apollographql.apollo3.exception.ApolloHttpException
import com.apollographql.apollo3.exception.ApolloNetworkException
import com.apollographql.apollo3.integration.normalizer.HeroAndFriendsNamesQuery
import com.apollographql.apollo3.integration.normalizer.HeroNameQuery
import com.apollographql.apollo3.integration.normalizer.type.Episode
import com.apollographql.apollo3.mockserver.MockServer
import com.apollographql.apollo3.mockserver.enqueueString
import com.apollographql.apollo3.testing.internal.runTest
Expand Down Expand Up @@ -63,10 +67,11 @@ class ExceptionsTest {
}
assertNotNull(result.exceptionOrNull())
}

@Test
@Suppress("DEPRECATION")
fun toFlowDoesNotThrowOnV3() = runTest(before = { setUp() }, after = { tearDown() }) {
mockServer.enqueueString("""
mockServer.enqueueString("""
{
"errors": [
{
Expand All @@ -81,8 +86,59 @@ class ExceptionsTest {
]
}
""".trimIndent())
val errorClient = apolloClient.newBuilder().useV3ExceptionHandling(true).build()
val response = errorClient.query(HeroNameQuery()).toFlow().toList()
assertTrue(response.first().errors?.isNotEmpty() ?: false)
val errorClient = apolloClient.newBuilder().useV3ExceptionHandling(true).build()
val response = errorClient.query(HeroNameQuery()).toFlow().toList()
assertTrue(response.first().errors?.isNotEmpty() ?: false)
}

private val PARTIAL_DATA_RESPONSE = """
{
"data": {
"hero": {
"name": "R2-D2",
"friends": null
}
},
"errors": [
{
"message": "Could not get friends",
"locations": [
{
"line": 1,
"column": 1
}
],
"path": [
"hero",
"friends"
]
}
]
}
""".trimIndent()

@Test
@Suppress("DEPRECATION")
fun v3ExceptionHandlingKeepsPartialData() = runTest(before = { setUp() }, after = { tearDown() }) {
mockServer.enqueueString(PARTIAL_DATA_RESPONSE)
val errorClient = apolloClient.newBuilder()
.useV3ExceptionHandling(true)
.build()
val response = errorClient.query(HeroAndFriendsNamesQuery(Episode.EMPIRE)).execute()
assertNotNull(response.data)
assertTrue(response.errors?.isNotEmpty() == true)
}

@Test
@Suppress("DEPRECATION")
fun v3ExceptionHandlingKeepsPartialDataWithCache() = runTest(before = { setUp() }, after = { tearDown() }) {
mockServer.enqueueString(PARTIAL_DATA_RESPONSE.trimIndent())
val errorClient = apolloClient.newBuilder()
.normalizedCache(MemoryCacheFactory(1024 * 1024))
.useV3ExceptionHandling(true)
.build()
val response = errorClient.query(HeroAndFriendsNamesQuery(Episode.EMPIRE)).execute()
assertNotNull(response.data)
assertTrue(response.errors?.isNotEmpty() == true)
}
}

0 comments on commit 00cc6ad

Please sign in to comment.