1

In my project that uses graphql-dotnet, I unexpectedly started getting errors saying the DataLoader context was null:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[1]
An unhandled exception has occurred while executing the request.
System.ArgumentNullException: Value cannot be null.
Parameter name: context
  at GraphQL.DataLoader.DataLoaderContextExtensions.GetOrAddBatchLoader[TKey,T](DataLoaderContext context, String loaderKey, Func`3 fetchFunc, IEqualityComparer`1 keyComparer, T defaultValue)

The context parameter comes from the IDataLoaderContextAccessor that is injected into the constructor of the graph type. Why would it be null?

Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147

2 Answers2

3

The context parameter will be null if you forget to add the DataLoaderDocumentListener before executing the query (like I did):

public GraphQLController(
    ISchema schema,
    IDocumentExecuter documentExecuter,
    DataLoaderDocumentListener dataLoaderListener)
{
    _schema = schema;
    _documentExecuter = documentExecuter;
    _dataLoaderListener = dataLoaderListener;
}

[HttpPost]
public async Task<IActionResult> Post([FromBody]BaseGraphQuery query)
{
    var inputs = query.Variables.ToInputs();
    var executionOptions = new ExecutionOptions
    {
        Schema = _schema,
        Query = query.Query,
        Inputs = inputs,
    };

    // Important!
    executionOptions.Listeners.Add(_dataLoaderListener);

    // (Execute the query)
}

And DataLoaderDocumentListener must be present in the service container:

public void ConfigureServices(IServiceCollection services)
{
    // (other service configuration)

    services.AddSingleton<GraphQL.DataLoader.IDataLoaderContextAccessor, GraphQL.DataLoader.DataLoaderContextAccessor>();
    services.AddSingleton<GraphQL.DataLoader.DataLoaderDocumentListener>();
    services.AddSingleton<GraphQL.IDocumentExecuter, GraphQL.DocumentExecuter>();
    services.AddSingleton<GraphQL.Types.ISchema, RootSchema>();
}

The accurate but vague error message confused me until I remembered I had "refactored" some code and removed the Listeners.Add line by mistake.

Nate Barbettini
  • 51,256
  • 26
  • 134
  • 147
-1

Also you need to make sure services.AddMvc(); is before all other stuff in startup.ConfigureServices()

flieks
  • 175
  • 1
  • 3
  • 13
  • The order of calls in `ConfigureServices` doesn't matter. It _does_ matter in `Configure`, because that is setting up a response pipeline. – Nate Barbettini Mar 26 '20 at 18:12
  • @NateBarbettini it is what i changed to get my Context filled because it was null before that change.. So not sure about that – flieks Mar 26 '20 at 22:22
  • Hmm, that is weird. Are you sure it was `ConfigureServices`? Simply changing the position of `AddMvc` caused a difference? My understanding of it could be wrong. – Nate Barbettini Mar 27 '20 at 00:55
  • Not certain because i changed maybe one other small thing which i think is not related. I know that the order of things in ConfigureServices can make a difference though – flieks Apr 01 '20 at 12:42