-
-
Notifications
You must be signed in to change notification settings - Fork 799
Open
Labels
Description
Product
Hot Chocolate
Version
15.1.11
Link to minimal reproduction
https://github.com/ChilliCream/graphql-platform
Steps to reproduce
Add and run this test:
public class TypeInterceptor_InputParserTests
{
public class TestingInterceptor : TypeInterceptor
{
public override void OnBeforeCompleteType(
ITypeCompletionContext completionContext,
DefinitionBase definition)
{
if (definition is InputObjectTypeDefinition objectDefinition)
{
// Problem reproduces whenever we modify an input type definition
// and that input type is used in another input type as a list element type,
// and an operation is executed providing a value of the modified input type in that list.
if (objectDefinition.Name == "SecondClassInput")
{
var field = new InputFieldDefinition
{
Name = "testInterceptorCalled",
Type = TypeReference.Parse("Boolean"),
};
objectDefinition.Fields.Add(field);
}
}
}
}
public class Query
{
public int Foo => 0;
}
public class Mutation
{
public CreateTestClassPayload CreateTestClass(CreateTestClassInput input) => new(new(input.TestClassId, input.Second.Select(x => new SecondClass(x.SecondId)).ToList()));
}
public record CreateTestClassPayload(TestClass? TestClass);
public record CreateTestClassInput(int TestClassId, List<SecondClassInput> Second);
public record TestClass(int TestClassId, List<SecondClass> Second);
public record SecondClass(int SecondId);
public record SecondClassInput(int SecondId);
[Fact]
public async Task AddingInterceptor_ShouldNotBreakInputParser()
{
var result = await new ServiceCollection()
.AddGraphQL()
.AddQueryType<Query>()
.AddMutationType<Mutation>()
.TryAddTypeInterceptor<TestingInterceptor>()
.ModifyRequestOptions(o => o.IncludeExceptionDetails = true)
.ExecuteRequestAsync("""
mutation {
createTestClass(input: {
testClassId: 123
second: [
{ secondId: 124 }
]
})
{
testClass {
testClassId
second {
secondId
}
}
}
}
""", cancellationToken: TestContext.Current.CancellationToken);
result.MatchInlineSnapshot("""
{
"data": {
"createTestClass": {
"testClass": {
"testClassId": 123,
"second": [
{
"secondId": 124
}
]
}
}
}
}
""");
}
}What is expected?
Operation executes, test passes.
What is actually happening?
Test fails with exception.
Relevant log output
Extracted error from exception details:
The value "System.Collections.Generic.Dictionary`2[System.String,System.Object]" is not of type "TypeInterceptor_InputParserTests+SecondClassInput" and cannot be used in this generic collection. (Parameter 'value')
at System.Collections.Generic.List`1.System.Collections.IList.Add(Object item)
at HotChocolate.Types.InputParser.ParseList(IValueNode resultValue, ListType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)
at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)
at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)
at HotChocolate.Types.InputParser.ParseObject(IValueNode resultValue, InputObjectType type, Path path, Int32 stack, Boolean defaults)
at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)
at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputFieldInfo field)
at HotChocolate.Types.InputParser.ParseLiteral(IValueNode value, IInputFieldInfo field, Type targetType)
at HotChocolate.Execution.Processing.MiddlewareContext.CoerceArgumentValue[T](ArgumentValue argument)
at HotChocolate.Execution.Processing.MiddlewareContext.ArgumentValue[T](String name)
at lambda_method3(Closure, IResolverContext)
at HotChocolate.Types.Helpers.FieldMiddlewareCompiler.<>c__DisplayClass9_0.<<CreateResolverMiddleware>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)
at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)Additional context
No response