From 8eea4aae67d6973263e3e351096f1625fe523547 Mon Sep 17 00:00:00 2001 From: Robert Balicki Date: Mon, 28 Nov 2022 18:02:14 -0800 Subject: [PATCH] Improve error messages related to @refetchable Summary: * Improve error messages related to refetchable * Note that our logic is wrong: * It looks like we currently accept interfaces, as long as all of their (directly) implementing objects implement Node. However, an interface is an "open" union, i.e. there could always be new concrete types that implement a given interface that we receive at runtime! These new types may not implement node, and we may not be able to refetch them. * There is also the separate bug that we should probably correctly handle recursively implementing objects, but that's a new addition so it makes sense that this bug exists. Reviewed By: tyao1 Differential Revision: D41507465 fbshipit-source-id: 99f3cf6d3603e5a6a4cf490d61b8115a6dbf36f1 --- .../fetchable_query_generator.rs | 3 ++- .../node_query_generator.rs | 2 +- ...ch-implementations-implement-node.expected} | 0 ...ich-implementations-implement-node.graphql} | 0 ...ations-not-implement-node.invalid.expected} | 6 +++--- ...tations-not-implement-node.invalid.graphql} | 0 .../tests/refetchable_fragment_test.rs | 18 +++++++++--------- 7 files changed, 15 insertions(+), 14 deletions(-) rename compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/{fragment-on-interface-which-implmentations-implement-node.expected => fragment-on-interface-which-implementations-implement-node.expected} (100%) rename compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/{fragment-on-interface-which-implmentations-implement-node.graphql => fragment-on-interface-which-implementations-implement-node.graphql} (100%) rename compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/{fragment-on-interface-which-implmentations-not-implement-node.invalid.expected => fragment-on-interface-which-implementations-not-implement-node.invalid.expected} (65%) rename compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/{fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql => fragment-on-interface-which-implementations-not-implement-node.invalid.graphql} (100%) diff --git a/compiler/crates/relay-transforms/src/refetchable_fragment/fetchable_query_generator.rs b/compiler/crates/relay-transforms/src/refetchable_fragment/fetchable_query_generator.rs index b53fcff66cb00..5e5516b936453 100644 --- a/compiler/crates/relay-transforms/src/refetchable_fragment/fetchable_query_generator.rs +++ b/compiler/crates/relay-transforms/src/refetchable_fragment/fetchable_query_generator.rs @@ -230,6 +230,7 @@ fn enforce_selections_with_id_field( } pub const FETCHABLE_QUERY_GENERATOR: QueryGenerator = QueryGenerator { - description: "@fetchable type", + // T138625502 we should support interfaces and maybe unions + description: "server objects with the @fetchable directive", build_refetch_operation, }; diff --git a/compiler/crates/relay-transforms/src/refetchable_fragment/node_query_generator.rs b/compiler/crates/relay-transforms/src/refetchable_fragment/node_query_generator.rs index 2d7b634231af8..4741417656af1 100644 --- a/compiler/crates/relay-transforms/src/refetchable_fragment/node_query_generator.rs +++ b/compiler/crates/relay-transforms/src/refetchable_fragment/node_query_generator.rs @@ -252,6 +252,6 @@ fn enforce_selections_with_id_field( } pub const NODE_QUERY_GENERATOR: QueryGenerator = QueryGenerator { - description: "the Node interface or types implementing the Node interface", + description: "the Node interface, object types that implement the Node interface, interfaces whose implementing objects all implement Node, and unions whose members all implement Node", build_refetch_operation, }; diff --git a/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.expected b/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.expected similarity index 100% rename from compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.expected rename to compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.expected diff --git a/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.graphql b/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.graphql similarity index 100% rename from compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.graphql rename to compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.graphql diff --git a/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.expected b/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.expected similarity index 65% rename from compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.expected rename to compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.expected index d756e091e5066..705d97dc7a11b 100644 --- a/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.expected +++ b/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.expected @@ -8,10 +8,10 @@ fragment UserName on UserNameRenderable ✖︎ Invalid use of @refetchable on fragment 'UserName', only supported are fragments on: - the Viewer type - the Query type - - the Node interface or types implementing the Node interface - - @fetchable type + - the Node interface, object types that implement the Node interface, interfaces whose implementing objects all implement Node, and unions whose members all implement Node + - server objects with the @fetchable directive - fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql:2:10 + fragment-on-interface-which-implementations-not-implement-node.invalid.graphql:2:10 1 │ # expected-to-throw 2 │ fragment UserName on UserNameRenderable │ ^^^^^^^^ diff --git a/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql b/compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.graphql similarity index 100% rename from compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql rename to compiler/crates/relay-transforms/tests/refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.graphql diff --git a/compiler/crates/relay-transforms/tests/refetchable_fragment_test.rs b/compiler/crates/relay-transforms/tests/refetchable_fragment_test.rs index 2a39562cefd7a..fe3426a328ce7 100644 --- a/compiler/crates/relay-transforms/tests/refetchable_fragment_test.rs +++ b/compiler/crates/relay-transforms/tests/refetchable_fragment_test.rs @@ -4,7 +4,7 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @generated SignedSource<<8cfbe364f914c89ce9b2405a88713948>> + * @generated SignedSource<> */ mod refetchable_fragment; @@ -13,17 +13,17 @@ use refetchable_fragment::transform_fixture; use fixture_tests::test_fixture; #[test] -fn fragment_on_interface_which_implmentations_implement_node() { - let input = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.graphql"); - let expected = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.expected"); - test_fixture(transform_fixture, "fragment-on-interface-which-implmentations-implement-node.graphql", "refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-implement-node.expected", input, expected); +fn fragment_on_interface_which_implementations_implement_node() { + let input = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.graphql"); + let expected = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.expected"); + test_fixture(transform_fixture, "fragment-on-interface-which-implementations-implement-node.graphql", "refetchable_fragment/fixtures/fragment-on-interface-which-implementations-implement-node.expected", input, expected); } #[test] -fn fragment_on_interface_which_implmentations_not_implement_node_invalid() { - let input = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql"); - let expected = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.expected"); - test_fixture(transform_fixture, "fragment-on-interface-which-implmentations-not-implement-node.invalid.graphql", "refetchable_fragment/fixtures/fragment-on-interface-which-implmentations-not-implement-node.invalid.expected", input, expected); +fn fragment_on_interface_which_implementations_not_implement_node_invalid() { + let input = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.graphql"); + let expected = include_str!("refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.expected"); + test_fixture(transform_fixture, "fragment-on-interface-which-implementations-not-implement-node.invalid.graphql", "refetchable_fragment/fixtures/fragment-on-interface-which-implementations-not-implement-node.invalid.expected", input, expected); } #[test]