-
-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"GraphQL.ExecutionError: Null value provided for non-nullable argument 'field1'" - Even though it is actually not null. #268
Comments
This one is probably a bug in GraphQL.NET’s new argument processing and not due to the use of the conventions project. Probably has to do with the use of the argument within the fragment. I’d be happy to fix it if we can reproduce the problem (with or without the conventions project). |
Attempting to replicate the test, can you see if this schema would somewhat match what you're attempting? # The Query type
type Query {
getStuff(path: [String!]!, filter: String): GetStuffResponse!
}
# Union type definition used in the fragment
union GetStuffResponse = UnionType1 | ErrorInfo
# Union member type with the fragment field
type UnionType1 {
more(field1: [String!]!): String!
}
# Error information type
type ErrorInfo {
errorMessage: String!
errorCode: String!
} If |
So far I cannot reproduce the problem within GraphQL.NET alone that fails using the above sample query. My code so far: using GraphQL.Types;
using Microsoft.Extensions.DependencyInjection;
namespace GraphQL.Tests.Bugs;
public class Bug268
{
[Theory]
[InlineData(
"""{ "var1": ["test"], "var2": ["test"], "var3": "test" }""",
"""{ "data": { "getStuff": { "more": "test", "__typename": "UnionType1" } } }""")]
[InlineData(
"""{ "var1": ["test432"], "var2": ["test"], "var3": "test" }""",
"""{ "data": { "getStuff": { "more": "test432", "__typename": "UnionType1" } } }""")]
[InlineData(
"""{ "var1": [], "var2": [], "var3": null }""",
"""{ "data": { "getStuff": { "more": null, "__typename": "UnionType1" } } }""")]
[InlineData(
"""{ "var1": ["test"], "var2": ["test"], "var3": "error" }""",
"""{ "data": { "getStuff": { "errorMessage": "Test1", "errorCode": "TestCode", "__typename": "ErrorInfo" }}}""")]
public async Task Sample_Matrix(string variablesJson, string expectedResponseJson)
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddGraphQL(b => b
.AddSchema<MySchema>()
.AddGraphTypes()
);
using var service = serviceCollection.BuildServiceProvider();
var schema = service.GetRequiredService<MySchema>();
var actualResponseJson = await schema.ExecuteAsync(_ =>
{
_.Query = """
query getStuffAndMore($var1: [String!]!, $var2: [String!]!, $var3: String) {
getStuff(path: $var2, filter: $var3) {
...Fragment1
... on ErrorInfo {
errorMessage
errorCode
__typename
}
__typename
}
}
fragment Fragment1 on UnionType1 {
more(field1: $var1)
}
""";
_.Variables = variablesJson.ToInputs();
});
actualResponseJson.ShouldBeCrossPlatJson(expectedResponseJson);
}
public class MySchema : Schema
{
public MySchema(IServiceProvider provider) : base(provider)
{
Query = provider.GetRequiredService<MyQuery>();
}
}
public class MyQuery : ObjectGraphType
{
public MyQuery()
{
Name = "Query";
Field<GetStuffResponseType>("getStuff")
.Argument<NonNullGraphType<ListGraphType<NonNullGraphType<StringGraphType>>>>("path")
.Argument<StringGraphType>("filter")
.Resolve(context => context.GetArgument<string>("filter") == "error"
? new ErrorInfo { ErrorMessage = "Test1", ErrorCode = "TestCode" }
: new UnionType1());
}
}
public class GetStuffResponseType : UnionGraphType
{
public GetStuffResponseType()
{
Name = "GetStuffResponse";
Type<UnionType1Type>();
Type<ErrorInfoType>();
}
}
public class UnionType1Type : ObjectGraphType<UnionType1>
{
public UnionType1Type()
{
Field<StringGraphType>("more")
.Argument<NonNullGraphType<ListGraphType<NonNullGraphType<StringGraphType>>>>("field1")
.Resolve(context => context.GetArgument<List<string>>("field1").FirstOrDefault());
}
}
public class UnionType1
{
}
public class ErrorInfoType : ObjectGraphType<ErrorInfo>
{
public ErrorInfoType()
{
Field(x => x.ErrorMessage);
Field(x => x.ErrorCode);
}
}
public class ErrorInfo
{
public string ErrorMessage { get; set; }
public string ErrorCode { get; set; }
}
} |
I'm looking at the Conventions project and I see |
If you can write a sample that reproduces the bug using the Conventions project, I can look further at this for you. |
Thanks for the support, and yeah, I will for sure do that. |
Hello again,
after I worked around #267 and then rolled out the new version, I discovered more obscure problems.
Some operations suddenly fail with the error mentioned in the title. No changes to the actual query or backend types were made.
The "ensure non null" validation seems to throw some new false positives.
If I remove the NonNull<> wrapper from that field it executes again, and there actually is a value!
This only happens on some operations. The thing that stands out about them is their complexity.
Looking at the request body, it's an operation with variables, which calls a query with one of the variables, and includes a fragment, which also uses a variable on one of it's methods.
An example:
I worked around it for now by removing the NonNull<> wrapper on the effected methods on the server side and instead added ArgumentNullException.ThrowIfNull() to the first line.
GraphQL: 8.2.1
GraphQL.Server.Transports.AspNetCore: 8.2.0
GraphQL.Convetions: 8.0.0
The text was updated successfully, but these errors were encountered: