graphql-dotnet: Still getting System.NullReferenceException in some case randomly, when interface is applied

Description

The system throw the Object reference not set to an instance of an object. and the whole API doesn’t work anymore. Same issue reported before in #978

I am using 4.5 and I can see some improvement was applied from last time I reported this issue, so I start to use the node interface feature back again. It is much better than before, last time the whole application must be crashed after a couple of hours, the new version I only get this issue once in 2 weeks from 4 environments.

Exception detail

System.NullReferenceException: Object reference not set to an instance of an object. at GraphQL.Types.SchemaTypes.ApplyTypeReference(IGraphType type) in /_/src/GraphQL/Types/Collections/SchemaTypes.cs:line 651 at GraphQL.Types.SchemaTypes.ApplyTypeReferences() in /_/src/GraphQL/Types/Collections/SchemaTypes.cs:line 614 at GraphQL.Types.SchemaTypes..ctor(ISchema schema, IServiceProvider serviceProvider) in /_/src/GraphQL/Types/Collections/SchemaTypes.cs:line 167 at GraphQL.Types.Schema.CreateSchemaTypes() in /_/src/GraphQL/Types/Schema.cs:line 328 at GraphQL.Types.Schema.Initialize() in /_/src/GraphQL/Types/Schema.cs:line 102 at GraphQL.DocumentExecuter.ExecuteAsync(ExecutionOptions options) in /_/src/GraphQL/Execution/DocumentExecuter.cs:line 80

Environment

GraphQL 4.5 on .NET 5

Duplication of interface

Beyond this, I also get a problem that the same interface might be applied to a graph type multiple times, this is happening in the latest version of 4.6 as well. Seems this problem is because the schema is add types synchronously, but it only does the duplication check on the entry of Interface function, so there are still a chance the ResolvedInterface can be added multiple times on the same type. This one can happen pretty frequently, if the schema has a lot types with interface applied, and those types are referenced in multiple places.

Below is my current work around to solve it in temp

    public abstract class NodeGraphType<TSource> : ObjectGraphType<TSource>, IObjectGraphType
    {
        public new void AddResolvedInterface(IInterfaceGraphType graphType)
        {
            if (!ResolvedInterfaces.Contains(graphType))
            {
                base.AddResolvedInterface(graphType);
            }
        }
    }

    public class NodeInterface : InterfaceGraphType, IInterfaceGraphType
    {
        public NodeInterface()
        {
            Name = "Node";
        }

        public new void AddPossibleType(IObjectGraphType type)
        {
            if (!PossibleTypes.Contains(type))
            {
                base.AddPossibleType(type);
            }
        }
    }

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 19 (15 by maintainers)

Most upvoted comments

I was getting memory leak when I was using field middleware feature.

Most assuredly. Every initialization wraps every field resolver with the middleware. Since the graphs were singletons, they would keep wrapping the delegate again and again for every request.