Hotchocolate: Value cannot be null for declaryingType when visting FieldInfo

Created on 19 Dec 2018  ยท  13Comments  ยท  Source: ChilliCream/hotchocolate

Hello all! I'm experiencing the following exception in my setup:

System.ArgumentNullException: Value cannot be null.
Parameter name: declaringType
   at HotChocolate.Validation.FieldSelectionMergingVisitor.FieldInfo..ctor(IType declaringType, FieldNode field)
   at HotChocolate.Validation.FieldSelectionMergingVisitor.VisitField(FieldNode field, IType type, ImmutableStack`1 path)
   at HotChocolate.Validation.QueryVisitor.VisitSelectionSet(SelectionSetNode selectionSet, IType type, ImmutableStack`1 path)
   at HotChocolate.Validation.QueryVisitor.VisitOperationDefinition(OperationDefinitionNode operation, ImmutableStack`1 path)
   at HotChocolate.Validation.FieldSelectionMergingVisitor.VisitDocument(DocumentNode document, ImmutableStack`1 path)
   at HotChocolate.Validation.QueryVisitorValidationErrorBase.Validate(ISchema schema, DocumentNode queryDocument)
   at HotChocolate.Validation.QueryValidator.Validate(DocumentNode query)
   at HotChocolate.Execution.QueryExecuter.CreateQueryInfo(String queryText)
   at HotChocolate.Runtime.Cache`1.GetOrCreate(String key, Func`1 create)
   at HotChocolate.Execution.QueryExecuter.ExecuteInternalAsync(QueryRequest request, CancellationToken cancellationToken)
   at HotChocolate.AspNetCore.QueryMiddlewareBase.HandleRequestAsync(HttpContext context, QueryExecuter queryExecuter)
   at HotChocolate.AspNetCore.QueryMiddlewareBase.InvokeAsync(HttpContext context)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.InvokeCore(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

My startup:

services.AddGraphQL(serviceProvider => Schema.Create(options =>
{
    options.RegisterServiceProvider(serviceProvider);
    options.RegisterQueryType<ObjectType<GraphQLRepository>>();
    options.RegisterType<InputObjectType<MapDefinition>>();
}));

My types:

public class GraphQLRepository
{
    private DbContext dbc;

    public GraphQLRepository(DbContext dbContext)
    {
        dbc = dbContext;
        productMatcher = matcher;
    }

    // This works!
    public async Task<List<EntityFrameworkType>> EntityFrameworkType() => await dbc.EntityFrameworkType.ToListAsync();

    // This produces the declaringType cannot be null exception.
    public async Task<int> AddNewMap(MapDefinition mapDefinition)
    {
        return 1;
    }
}

public class MapDefinition
{
    public int Id { get; set; }
}

I think I'm missing a fundamental concept here...trying to figure it out through the docs and what not. I believe it has something to do with parsing the MapDefinition argument of AddNewMap. I've tried IType, and Object/InputObject inheritance wrappers. I've also enabled trace level logs in appSettings. Is there any way I can drill deeper?

โ“ question

All 13 comments

Which version of hotchocolate are you using?

Ah yes! I'm using version 0.6.11.

Ok, I will have a look at it.

Hi, I have setup a little test server but cannot reproduce the error... could you also send me the query. that you are sending to the server?

Mine looks something like this

{
  addNewMap(mapDefinition:{id:1})
}

I set my server up like this:

 public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddGraphQL(sp => Schema.Create(c =>
            {
                c.RegisterServiceProvider(sp);
                c.RegisterQueryType<ObjectType<GraphQLRepository>>();
                c.RegisterType<InputObjectType<MapDefinition>>();
            }));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            // enable this if you want tu support subscription
            // app.UseWebSockets();
            app.UseGraphQL();
            app.UseGraphiQL();
        }
    }

    public class GraphQLRepository
    {

        public GraphQLRepository()
        {

        }


        // This produces the declaringType cannot be null exception.
        public async Task<int> AddNewMap(MapDefinition mapDefinition)
        {
            return 1;
        }
    }

    public class MapDefinition
    {
        public int Id { get; set; }
    }

Hello, my GraphQL query looks like this:

mutation
{
  addnewMap(mapDefinition: { id: 1 })
}

Leaving out mutation results in an error:
The field addnewMap does not exist on the type GraphQLRepository.

I admit I'm not well versed in GraphQL verbs.

I think our setups look the same. I'm using the Playground though rather than GraphiQL - which I couldn't figure out on my end.

app.UseGraphQL();
app.UsePlayground();

Ah, if you want that as mutation than you have to declare your type as mutation. You registered it as query. Still there should not be an exception like this. Try RegisterMutationType

Hello! Didn't mean to close this just yet, but I do think I got it.

I was writing: addnewMap not addNewMap - jeez! So the query works just fine without 'mutation'. If you have a moment, could you educate me on what a mutation is an when its a applicable? If not no worries I'll head on over to the GraphQL docs.

I want to try one more thing and this should be good to go (besides the potentially unexpected error?).

Hello, how do I properly register and query a class like this?

    public class MapDefinition
    {
        public MapOptions Options { get; set; }
        public List<ColumnMap> ColumnMaps { get; set; }
    }

The List is giving me some trouble.

I'll head on over to the GraphQL docs.

GraphQL.org is a good place to start.
We have created an example server that implements their demo schema.
HotChocolate StarWars Server

I admit I'm not well versed in GraphQL verbs.

In GraphQL you have basically three root types: Query, Mutation, Subscription

Queries is for read-only data consumption and all fields of a query are resolved in-parallel
Mutations are for modifying data. The top-level mutation fields are resolved serial.
Subscriptions represents queries that open up a response stream, basically it is for events/messages.

I think you should first read through the GraphQL.org examples because there is a lot more to know. We are currently working on a tutorial that explains those things but it is not ready yet. So, GraphQL.org is the best place to get stated.

Hello, how do I properly register and query a class like this?

Let's say we take you initial example....

Then map data. would be an InputObjectType. So a query with an InputObjectType payload would look like the following:

{
  addnewMap(mapDefinition: { options: { field1: "abc" field2: 123 } columnMaps:[ { field1: "abc" field2: 123 } ]  })
}

GraphQL does not need commas to delimit fields.

So for the next thing I will use the following schema:

type Query {
  foo: [Foo]
}

type Foo {
  bar: String
}

So, the query to ask for the list is the same if it were a complex type (ObjectType/InterfaceType)

{
 foo {
   bar
 }
}

I will close this issue now and hope the infos helped you.... have fun learning GraphQL :)

I have opened a new issue #411 for the nullrefexception.... we will fix that with the next release. Although the query was invalid there should never be a nullrefexception from the system. Thanks for reporting that.

Was this page helpful?
0 / 5 - 0 ratings