FSharp.Data.GraphQL icon indicating copy to clipboard operation
FSharp.Data.GraphQL copied to clipboard

bugfix/issue-353-invalid-introspection

Open njlr opened this issue 3 years ago • 7 comments

This is a fix for https://github.com/fsprojects/FSharp.Data.GraphQL/issues/353.

Currently the implementation does not generate a valid introspection query result when default values are specified.

According to the spec:

defaultValue may return a String encoding (using the GraphQL language) of the default value used by this input value in the condition a value is not provided at runtime. If this input value has no default value, returns null.

Before the fix:

-                  "defaultValue": "this is the default value"

After the fix:

+                  "defaultValue": "\"this is the default value\""

This PR adds a Serialize method to all input type definitions (InputDef) that takes a .NET instance for that type definition and generates a GraphQL value:

        /// Serializes the associated .NET CLR type into a GQL value
        abstract member Serialize : obj -> Ast.Value

This is used to generate a valid string during introspection.

By default, a serializer is automatically generated using reflection, so there is no need for the user to do anything. However, there is the opportunity to pass a custom serializer for full control over the output.

njlr avatar Oct 01 '22 08:10 njlr

Do you know why tests fail? Maybe a test case is wrong?

xperiandri avatar Oct 01 '22 11:10 xperiandri

I am not sure why the build is failing.

The following works for me:

# Terminal 1
dotnet run --project ./tests/FSharp.Data.GraphQL.IntegrationTests.Server

# Terminal 2
dotnet run --project ./samples/star-wars-api

# Terminal 3
dotnet test ./FSharp.Data.GraphQL.sln
dotnet test ./FSharp.Data.GraphQL.Integration.sln

njlr avatar Oct 01 '22 11:10 njlr

If you will not be managed to fix this I will take action on this PR after a few other PRs. Expected next week

xperiandri avatar Oct 01 '22 11:10 xperiandri

If you will not be managed to fix this I will take action on this PR after a few other PRs. Expected next week

Success! The tests pass now.

njlr avatar Oct 03 '22 17:10 njlr

@njlr, could you rebase, solve conflicts and add me to your repo as contributor so that I can fix something if necessary?

xperiandri avatar Oct 07 '22 22:10 xperiandri

@njlr, could you rebase, solve conflicts and add me to your repo as contributor so that I can fix something if necessary?

Fixed now?

njlr avatar Oct 08 '22 10:10 njlr

Yes, great, thanks!

xperiandri avatar Oct 08 '22 10:10 xperiandri

@njlr now we have

The active test run was aborted. Reason: Test host process crashed : Stack overflow.
   at System.ModuleHandle.ResolveMethod(System.Runtime.CompilerServices.QCallModule, Int32, IntPtr*, Int32, IntPtr*, Int32)
   at System.ModuleHandle.ResolveMethodHandleInternal(System.Reflection.RuntimeModule, Int32, IntPtr[], Int32, IntPtr[], Int32)
   at System.ModuleHandle.ResolveMethodHandle(Int32, System.RuntimeTypeHandle[], System.RuntimeTypeHandle[])
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(System.Reflection.MetadataToken, System.Reflection.MetadataImport ByRef, System.Reflection.RuntimeModule, System.Reflection.MetadataToken, System.RuntimeType, Boolean, ListBuilder`1<System.Object> ByRef, System.RuntimeType ByRef, System.IRuntimeMethodInfo ByRef, Boolean ByRef)
   at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1<System.Object> ByRef, System.Reflection.RuntimeModule, Int32, System.RuntimeType, Boolean, ListBuilder`1<System.Object>)
   at System.Reflection.RuntimePropertyInfo.GetCustomAttributes(System.Type, Boolean)
   at Microsoft.FSharp.Reflection.Impl.tryFindCompilationMappingAttributeFromMemberInfo(System.Reflection.MemberInfo)
   at Microsoft.FSharp.Reflection.Impl.isFieldProperty(System.Reflection.PropertyInfo)
   at Microsoft.FSharp.Collections.ArrayModule+Filter.createMask[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Boolean>, System.__Canon[], UInt32[] ByRef, UInt32 ByRef)
   at Microsoft.FSharp.Collections.ArrayModule+Filter.filter[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Boolean>, System.__Canon[])
   at Microsoft.FSharp.Reflection.Impl.fieldPropsOfRecordType(System.Type, System.Reflection.BindingFlags)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto

xperiandri avatar Dec 06 '22 16:12 xperiandri

@njlr now we have

The active test run was aborted. Reason: Test host process crashed : Stack overflow.
   at System.ModuleHandle.ResolveMethod(System.Runtime.CompilerServices.QCallModule, Int32, IntPtr*, Int32, IntPtr*, Int32)
   at System.ModuleHandle.ResolveMethodHandleInternal(System.Reflection.RuntimeModule, Int32, IntPtr[], Int32, IntPtr[], Int32)
   at System.ModuleHandle.ResolveMethodHandle(Int32, System.RuntimeTypeHandle[], System.RuntimeTypeHandle[])
   at System.Reflection.CustomAttribute.FilterCustomAttributeRecord(System.Reflection.MetadataToken, System.Reflection.MetadataImport ByRef, System.Reflection.RuntimeModule, System.Reflection.MetadataToken, System.RuntimeType, Boolean, ListBuilder`1<System.Object> ByRef, System.RuntimeType ByRef, System.IRuntimeMethodInfo ByRef, Boolean ByRef)
   at System.Reflection.CustomAttribute.AddCustomAttributes(ListBuilder`1<System.Object> ByRef, System.Reflection.RuntimeModule, Int32, System.RuntimeType, Boolean, ListBuilder`1<System.Object>)
   at System.Reflection.RuntimePropertyInfo.GetCustomAttributes(System.Type, Boolean)
   at Microsoft.FSharp.Reflection.Impl.tryFindCompilationMappingAttributeFromMemberInfo(System.Reflection.MemberInfo)
   at Microsoft.FSharp.Reflection.Impl.isFieldProperty(System.Reflection.PropertyInfo)
   at Microsoft.FSharp.Collections.ArrayModule+Filter.createMask[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Boolean>, System.__Canon[], UInt32[] ByRef, UInt32 ByRef)
   at Microsoft.FSharp.Collections.ArrayModule+Filter.filter[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.FSharp.Core.FSharpFunc`2<System.__Canon,Boolean>, System.__Canon[])
   at Microsoft.FSharp.Reflection.Impl.fieldPropsOfRecordType(System.Type, System.Reflection.BindingFlags)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)
   at FSharp.Data.GraphQL.Serialization.Auto.generateSerializerInteral(System.Type)

Looks like an issue with the code that automatically generates a serializer using reflection.

Do you know the .NET type causing the issue? I can make a fix and add a test.

njlr avatar Dec 06 '22 17:12 njlr

Yes, please

xperiandri avatar Dec 07 '22 03:12 xperiandri

Yes, please

Do you know the .NET type?

njlr avatar Dec 07 '22 11:12 njlr

No

xperiandri avatar Dec 07 '22 14:12 xperiandri

No

I managed to reproduce the issue with a recursive record definition. There is now a fix and a test for this.

njlr avatar Dec 09 '22 20:12 njlr

Perfect! Could you also rebase it on the latest dev, please?

xperiandri avatar Dec 09 '22 20:12 xperiandri

Perfect! Could you also rebase it on the latest dev, please?

OK I think it's ready

njlr avatar Dec 09 '22 21:12 njlr

Thank you very much! I'll use that in my refactoring

xperiandri avatar Dec 09 '22 21:12 xperiandri