Skip to content

Commit 7c6ba5e

Browse files
[Fusion] Handle invalid @is usages more gracefully (#8740)
1 parent ac31ff0 commit 7c6ba5e

File tree

4 files changed

+135
-79
lines changed

4 files changed

+135
-79
lines changed

src/HotChocolate/Fusion-vnext/src/Fusion.Utilities/Properties/FusionUtilitiesResources.Designer.cs

Lines changed: 18 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/HotChocolate/Fusion-vnext/src/Fusion.Utilities/Properties/FusionUtilitiesResources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,7 @@
6969
<data name="SelectionSetValidator_UnionFieldInvalidSelections" xml:space="preserve">
7070
<value>The field '{0}' returns a union type and must only include inline fragment selections.</value>
7171
</data>
72+
<data name="FieldSelectionMapValidator_InvalidFieldParentType" xml:space="preserve">
73+
<value>Expected the parent type of field '{0}' to be a complex type but received '{1}'.</value>
74+
</data>
7275
</root>

src/HotChocolate/Fusion-vnext/src/Fusion.Utilities/Validators/FieldSelectionMapValidator.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ protected override ISyntaxVisitorAction Enter(
122122
PathSegmentNode node,
123123
FieldSelectionMapValidatorContext context)
124124
{
125-
if (context.OutputTypes.Peek().NullableType() is IComplexTypeDefinition complexType)
125+
var outputType = context.OutputTypes.Peek();
126+
if (outputType.NullableType() is IComplexTypeDefinition complexType)
126127
{
127128
if (!complexType.Fields.TryGetField(node.FieldName.Value, out var field))
128129
{
@@ -146,7 +147,7 @@ protected override ISyntaxVisitorAction Enter(
146147
context.Errors.Add(
147148
string.Format(
148149
FieldSelectionMapValidator_FieldMissingTypeCondition,
149-
node.FieldName));
150+
node.FieldName.Value));
150151

151152
return Break;
152153
}
@@ -201,6 +202,16 @@ protected override ISyntaxVisitorAction Enter(
201202
context.TerminalTypes.Push(field.Type);
202203
}
203204
}
205+
else
206+
{
207+
context.Errors.Add(
208+
string.Format(
209+
FieldSelectionMapValidator_InvalidFieldParentType,
210+
node.FieldName.Value,
211+
outputType));
212+
213+
return Break;
214+
}
204215

205216
if (node.TypeName is { } typeName)
206217
{

src/HotChocolate/Fusion-vnext/test/Fusion.Composition.Tests/PostMergeValidationRules/IsInvalidFieldRuleTests.cs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,27 @@ type Person {
7373
}
7474
"""
7575
]
76+
},
77+
{
78+
[
79+
"""
80+
# Schema A
81+
type Query {
82+
personByName(name: String! @is(field: "name")): Person @lookup
83+
}
84+
85+
type Person {
86+
id: ID!
87+
}
88+
""",
89+
"""
90+
# Schema B
91+
type Person {
92+
id: ID!
93+
name: String!
94+
}
95+
"""
96+
]
7697
}
7798
};
7899
}
@@ -101,6 +122,86 @@ type Person {
101122
"The @is directive on argument 'Query.personById(id:)' in schema 'A' "
102123
+ "specifies an invalid field selection against the composed schema."
103124
]
125+
},
126+
// Type of argument does not match field type.
127+
{
128+
[
129+
"""
130+
# Schema A
131+
type Query {
132+
personById(id: Int! @is(field: "id")): Person @lookup
133+
}
134+
135+
type Person {
136+
id: ID!
137+
name: String
138+
}
139+
"""
140+
],
141+
[
142+
"The @is directive on argument 'Query.personById(id:)' in schema 'A' "
143+
+ "specifies an invalid field selection against the composed schema."
144+
]
145+
},
146+
// List output type, Singular input type.
147+
{
148+
[
149+
"""
150+
# Schema A
151+
type Query {
152+
personsById(id: ID! @is(field: "id")): [Person!]! @lookup
153+
}
154+
155+
type Person {
156+
id: ID!
157+
name: String
158+
}
159+
"""
160+
],
161+
[
162+
"The @is directive on argument 'Query.personsById(id:)' in schema 'A' "
163+
+ "specifies an invalid field selection against the composed schema."
164+
]
165+
},
166+
// Singular output type, List input type.
167+
{
168+
[
169+
"""
170+
# Schema A
171+
type Query {
172+
personByIds(ids: [ID!]! @is(field: "id")): Person! @lookup
173+
}
174+
175+
type Person {
176+
id: ID!
177+
name: String
178+
}
179+
"""
180+
],
181+
[
182+
"The @is directive on argument 'Query.personByIds(ids:)' in schema 'A' "
183+
+ "specifies an invalid field selection against the composed schema."
184+
]
185+
},
186+
// List output type, List input type (valid for Fusion v1 batch lookups).
187+
{
188+
[
189+
"""
190+
# Schema A
191+
type Query {
192+
personsByIds(ids: [ID!]! @is(field: "id")): [Person!]! @lookup
193+
}
194+
195+
type Person {
196+
id: ID!
197+
name: String
198+
}
199+
"""
200+
],
201+
[
202+
"The @is directive on argument 'Query.personsByIds(ids:)' in schema 'A' "
203+
+ "specifies an invalid field selection against the composed schema."
204+
]
104205
}
105206
};
106207
}

0 commit comments

Comments
 (0)