From eecfdd77e7216e840524f995dc9bfc78970dd5c9 Mon Sep 17 00:00:00 2001 From: BoD Date: Fri, 14 Mar 2025 11:43:55 +0100 Subject: [PATCH] Don't call MetadataGenerator on error fields --- .../cache/normalized/internal/Normalizer.kt | 8 +++- .../pagination/connection/schema.graphqls | 2 +- .../kotlin/ConnectionPaginationTest.kt | 40 ++++++++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/internal/Normalizer.kt b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/internal/Normalizer.kt index 1a0b02a0..f2097106 100644 --- a/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/internal/Normalizer.kt +++ b/normalized-cache-incubating/src/commonMain/kotlin/com/apollographql/cache/normalized/internal/Normalizer.kt @@ -112,7 +112,11 @@ internal class Normalizer( path = base.append(fieldKey), embeddedFields = embeddedFieldsProvider.getEmbeddedFields(EmbeddedFieldsContext(parentType)), ) - val metadata = metadataGenerator.metadataForObject(entry.value, MetadataGeneratorContext(field = mergedField, variables)) + val metadata = if (entry.value is Error) { + emptyMap() + } else { + metadataGenerator.metadataForObject(entry.value, MetadataGeneratorContext(field = mergedField, variables)) + } fieldKey to FieldInfo(value, metadata) }.toMap() @@ -164,7 +168,7 @@ internal class Normalizer( * * This function builds the list of records as a side effect * - * @param value a json value from the response. Can be any type supported by [com.apollographql.apollo.api.json.JsonWriter] + * @param value a json value from the response. Can be [com.apollographql.apollo.api.json.ApolloJsonElement] or [Error] * @param field the field currently being normalized * @param type_ the type currently being normalized. It can be different from `field.type` for lists. * @param embeddedFields the embedded fields of the parent diff --git a/tests/pagination/src/commonMain/graphql/pagination/connection/schema.graphqls b/tests/pagination/src/commonMain/graphql/pagination/connection/schema.graphqls index e66078a5..f825cd95 100644 --- a/tests/pagination/src/commonMain/graphql/pagination/connection/schema.graphqls +++ b/tests/pagination/src/commonMain/graphql/pagination/connection/schema.graphqls @@ -1,5 +1,5 @@ type Query { - users(first: Int = 10, after: String = null, last: Int = null, before: String = null): UserConnection! + users(first: Int = 10, after: String = null, last: Int = null, before: String = null): UserConnection } type UserConnection { diff --git a/tests/pagination/src/commonTest/kotlin/ConnectionPaginationTest.kt b/tests/pagination/src/commonTest/kotlin/ConnectionPaginationTest.kt index deca3d04..5bab8abb 100644 --- a/tests/pagination/src/commonTest/kotlin/ConnectionPaginationTest.kt +++ b/tests/pagination/src/commonTest/kotlin/ConnectionPaginationTest.kt @@ -1,5 +1,6 @@ package pagination +import com.apollographql.apollo.api.Error import com.apollographql.apollo.api.Optional import com.apollographql.apollo.testing.internal.runTest import com.apollographql.cache.normalized.ApolloStore @@ -344,5 +345,42 @@ class ConnectionPaginationTest { assertEquals(data5, dataFromStore) assertChainedCachesAreEqual(apolloStore) } -} + + @Test + fun errorMemoryCache() { + errorTest(MemoryCacheFactory()) + } + + @Test + fun errorSqlCache() { + errorTest(SqlNormalizedCacheFactory()) + } + + @Test + fun errorChainedCache() { + errorTest(MemoryCacheFactory().chain(SqlNormalizedCacheFactory())) + } + + private fun errorTest(cacheFactory: NormalizedCacheFactory) = runTest { + val apolloStore = ApolloStore( + normalizedCacheFactory = cacheFactory, + cacheKeyGenerator = TypePolicyCacheKeyGenerator, + metadataGenerator = ConnectionMetadataGenerator(Pagination.connectionTypes), + cacheResolver = FieldPolicyCacheResolver, + recordMerger = ConnectionRecordMerger + ) + apolloStore.clearAll() + val query = UsersQuery(first = Optional.Present(2)) + apolloStore.writeOperation( + operation = query, + data = UsersQuery.Data { users = null }, + errors = listOf(Error.Builder("An error occurred.").path(listOf("users")).build()) + ) + val responseFromStore = apolloStore.readOperation(query) + assertEquals(UsersQuery.Data { users = null }, responseFromStore.data) + assertEquals(1, responseFromStore.errors?.size) + assertEquals("An error occurred.", responseFromStore.errors?.firstOrNull()?.message) + assertEquals(listOf("users"), responseFromStore.errors?.firstOrNull()?.path) + } +}