graphql-platform icon indicating copy to clipboard operation
graphql-platform copied to clipboard

Missing optional value in input type throws exception

Open svelue opened this issue 2 years ago • 11 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

Describe the bug

In contrast to V11 a mutation fails if an optional input field is not set and the field is mapped to a non nullable property.

Steps to reproduce

  1. Checkout and start https://github.com/svelue/OptionalInputBug
  2. Run mutation{ addBook(book: {title: "123", someNumber: 1}){ title someNumber } } --> it works
  3. Run mutation{ addBook(book: {title: "123"}){ title someNumber } } --> it fails

Relevant log output

+        "Message": "Unexpected Execution Error",
+        "Code": null,
+        "Path": {
+          "Parent": null,
+          "Depth": 0,
+          "Name": "sendData"
+        },
+        "Locations": [
+          {
+            "Line": 2,
+            "Column": 3
+          }
+        ],
+        "Extensions": null,
+        "Exception": {
+          "ClassName": "System.NullReferenceException",
+          "Message": "Object reference not set to an instance of an object.",
+          "Data": null,
+          "InnerException": null,
+          "HelpURL": null,
+          "StackTraceString": "   at lambda_method858(Closure , Object[] )\r\n   at HotChocolate.Types.InputParser.ParseObject(IValueNode resultValue, InputObjectType type, Path path, Int32 stack, Boolean defaults)\r\n   at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputField field)\r\n   at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputField field)\r\n   at HotChocolate.Types.InputParser.ParseList(IValueNode resultValue, ListType type, Path path, Int32 stack, Boolean defaults, IInputField field)\r\n   at HotChocolate.Types.InputParser.ParseLiteralInternal(IValueNode value, IType type, Path path, Int32 stack, Boolean defaults, IInputField field)\r\n   at HotChocolate.Types.InputParser.ParseLiteral(IValueNode value, IInputField field, Type targetType)\r\n   at HotChocolate.Execution.Processing.MiddlewareContext.CoerceArgumentValue[T](ArgumentValue argument)\r\n   at HotChocolate.Execution.Processing.MiddlewareContext.ArgumentValue[T](NameString name)\r\n   at HotChocolate.Execution.Processing.DirectiveContext.ArgumentValue[T](NameString name)\r\n   at lambda_method1081(Closure , IResolverContext )\r\n   at HotChocolate.Types.Helpers.FieldMiddlewareCompiler.<>c__DisplayClass9_0.<<CreateResolverMiddleware>b__0>d.MoveNext()\r\n--- End of stack trace from previous location ---\r\n   at HotChocolate.AspNetCore.Authorization.AuthorizeMiddleware.InvokeAsync(IDirectiveContext context)\r\n   at HotChocolate.Utilities.MiddlewareCompiler`1.ExpressionHelper.AwaitTaskHelper(Task task)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.ExecuteResolverPipelineAsync(CancellationToken cancellationToken)\r\n   at HotChocolate.Execution.Processing.Tasks.ResolverTask.TryExecuteAsync(CancellationToken cancellationToken)",
+          "RemoteStackTraceString": null,
+          "RemoteStackIndex": 0,
+          "ExceptionMethod": null,
+          "HResult": -2147467261,
+          "Source": "Anonymously Hosted DynamicMethods Assembly",
+          "WatsonBuckets": null
+        },

Additional Context?

https://hotchocolategraphql.slack.com/archives/CD9TNKT8T/p1635433560328800

Product

Hot Chocolate

Version

12.0.1

svelue avatar Oct 29 '21 06:10 svelue

This is an issue for us as well. I thought it only occurred via enums... Our current workaround is to make those types nullable, but resolving that in our BLL is quite the pain.

KreativJos avatar Nov 29 '21 11:11 KreativJos

@KreativJos Optional does not mean nullable. See more for context (https://github.com/ChilliCream/hotchocolate/issues/1808)

PascalSenn avatar Nov 29 '21 11:11 PascalSenn

@PascalSenn That was not what I was referencing to. I have GraphQLTypes which reference models with optional values:

descriptor.Field(t => t.AuthorType).Type<AuthorTypeEnumType>();

public Optional<AuthorTypeEnum> AuthorType { get; set; }

With the annotation-method, it looks like this:

[GraphQLType(typeof(AuthorTypeEnumType))]
public Optional<AuthorTypeEnum> AuthorType { get; set; }

KreativJos avatar Nov 29 '21 11:11 KreativJos

Yeah, but Optional is only meant for arguments to be able to differentiate between it being null or a default value. As far as I'm aware the are no default values for object type fields, so optional doesn't make sense here. Just get rid of the optional and your code should function as normal, considering thr nullability is already set by you, specifiying thr type.

tobias-tengler avatar Nov 29 '21 13:11 tobias-tengler

But I want to know if the user has explicitly set the field, which is what Optional<> is meant for...

KreativJos avatar Nov 29 '21 13:11 KreativJos

Sorry my bad I thought you were using Optional on object type fields and not on input object types. My bad!

tobias-tengler avatar Nov 29 '21 13:11 tobias-tengler

Do we have any ETA for this issue? Because of this, we currently cannot switch to HC12.

KreativJos avatar Feb 21 '22 10:02 KreativJos

Wondering if this is stale for a reason? Are you no longer planning to address this in an upcoming release?

pguidoPokerAtlas avatar May 04 '22 00:05 pguidoPokerAtlas

This issue should not be stale - a solution should be available. I personally cannot help, because it is not a surface issue. I unfortunately do not have enough knowledge of the HC system to solve it.

KreativJos avatar Jul 04 '22 13:07 KreativJos

Experiencing the same problem, in V11 this worked, in V12 it results in this hard to track down NullReferenceException. As a workaround, we currently use the default GUID value for non-nullable Guids and use reflection to map them in the database.

nikonthethird avatar Aug 18 '22 14:08 nikonthethird

This is a bug. The issue is that the input parser assumes a Nullable but finds an in as a prop. I am working on this now.

michaelstaib avatar Aug 19 '22 08:08 michaelstaib

https://github.com/ChilliCream/hotchocolate/pull/5317

michaelstaib avatar Aug 19 '22 09:08 michaelstaib

This is now fixed and integrated into 12.13.0-preview.2

michaelstaib avatar Aug 19 '22 10:08 michaelstaib

Thank you very much, we tested it and it appears the HotChocolate 11 behavior has been restored.

nikonthethird avatar Aug 22 '22 10:08 nikonthethird

Thanks a lot. The 12.13.0-preview.2 package seems to fix the described problem for my team as well!

I'm finally able to remove all the descriptor.DefaultValue / reflection shenanigans we've been using as a workaround.

accarin avatar Aug 22 '22 13:08 accarin