question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NPE in CacheProvider caused by adding default values for variables

See original GitHub issue

Hi @bbakerman @andimarek,

I implemented a CacheProvider:

public class CacheProvider implements PreparsedDocumentProvider {

    @Resource
    private Cache<String, PreparsedDocumentEntry> cache;

    @Override
    public PreparsedDocumentEntry getDocument(final ExecutionInput executionInput,
            final Function<ExecutionInput, PreparsedDocumentEntry> computeFunction) {

        final Function<String, PreparsedDocumentEntry> mapCompute = key -> {
            try {
                return computeFunction.apply(executionInput);
            } catch (Exception e) {
                throw new IllegalArgumentException(String.format("Failed to compute cache key for query: %s . variables: %s",
                        executionInput.getQuery(), executionInput.getVariables()));
            }
        };

        return cache.get(executionInput.getQuery(), mapCompute);
    }

}

I got a NPE when I call computeFunction.apply(executionInput) with this kind of queries:

query search($texte: String = "", $includetest: Boolean = true){
  search(query: $texte) {
	  test @include(if: $includetest){
	      ...testFragment
	  }
  }
}

Variables:

{
    "texte": "work"
}

If I add includetest in my variables, it works. Is it the expected behavior ?

Default variables 
Default values can also be assigned to the variables in the query by adding the default value after the type declaration.

query HeroNameAndFriends($episode: Episode = JEDI) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
When default values are provided for all variables, you can call the query without passing any variables. If any variables are passed as part of the variables dictionary, they will override the defaults.

Infos:

  <caffeine.version>2.8.6</caffeine.version>
  <graphql-java.version>15.0</graphql-java.version>

Thanks

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
bbakermancommented, Nov 5, 2020

eg

        Map<String, Object> inputVariables = executionInput.getVariables();
        List<VariableDefinition> variableDefinitions = operationDefinition.getVariableDefinitions();

        Map<String, Object> coercedVariables;
        try {
            coercedVariables = valuesResolver.coerceVariableValues(graphQLSchema, variableDefinitions, inputVariables);
        } catch (RuntimeException rte) {
            if (rte instanceof GraphQLError) {
                return completedFuture(new ExecutionResultImpl((GraphQLError) rte));
            }
            throw rte;
        }

This type of code.

The work around here is to define the conditional variables explicitly until this bug is fixed when using these instrumentions

1reaction
bbakermancommented, Nov 5, 2020

I am able to reproduce this a bug

 def sdl = """ 
                type Query { foo : FooType }
                type FooType { bar : String }
                """
        def instrumentation = new ChainedInstrumentation([
                new MaxQueryComplexityInstrumentation(20),
                new MaxQueryDepthInstrumentation(20)
        ])
        def graphQL = TestUtil.graphQL(sdl)
                .instrumentation(instrumentation)
                .build()

        when:
        def er = graphQL.execute('''
            query withDefaults( $var : Boolean = true) {
                foo @include(if: $var) {
                    bar
                }
            }
        ''')

        then:
        er.errors.isEmpty()

java.lang.NullPointerException
	at graphql.execution.ConditionalNodes.getDirectiveResult(ConditionalNodes.java:39)
	at graphql.execution.ConditionalNodes.shouldInclude(ConditionalNodes.java:24)
	at graphql.analysis.NodeVisitorWithTypeTracking.visitField(NodeVisitorWithTypeTracking.java:173)
	at graphql.language.Field.accept(Field.java:191)
	at graphql.language.NodeTraverser$1.enter(NodeTraverser.java:61)
	at graphql.util.Traverser.traverse(Traverser.java:144)
	at graphql.language.NodeTraverser.doTraverse(NodeTraverser.java:149)
	at graphql.language.NodeTraverser.depthFirst(NodeTraverser.java:69)
	at graphql.analysis.QueryTraverser.visitImpl(QueryTraverser.java:178)
	at graphql.analysis.QueryTraverser.visitPostOrder(QueryTraverser.java:83)
	at graphql.analysis.MaxQueryComplexityInstrumentation.lambda$beginValidation$4(MaxQueryComplexityInstrumentation.java:88)
	at graphql.execution.instrumentation.SimpleInstrumentationContext.onCompleted(SimpleInstrumentationContext.java:48)
	at graphql.execution.instrumentation.ChainedInstrumentation$ChainedInstrumentationContext.lambda$onCompleted$1(ChainedInstrumentation.java:258)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at java.util.Collections$UnmodifiableCollection.forEach(Collections.java:1080)
	at graphql.execution.instrumentation.ChainedInstrumentation$ChainedInstrumentationContext.onCompleted(ChainedInstrumentation.java:258)
	at graphql.GraphQL.validate(GraphQL.java:588)
	at graphql.GraphQL.parseAndValidate(GraphQL.java:550)
	at graphql.GraphQL.lambda$parseValidateAndExecute$5(GraphQL.java:519)
	at graphql.execution.preparsed.NoOpPreparsedDocumentProvider.getDocument(NoOpPreparsedDocumentProvider.java:15)
	at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:521)
	at graphql.GraphQL.executeAsync(GraphQL.java:490)
	at graphql.GraphQL.execute(GraphQL.java:421)
	at graphql.GraphQL.execute(GraphQL.java:303)
	at graphql.execution.ConditionalNodesTest.can default conditional node values(ConditionalNodesTest.groovy:57)

It’s caused by ConditionalNodes being invoked BUT the variable coercer has not run yet to default the variables (which happens after parse/validate.

Both of these instrumentions call

        QueryTraverser queryTraverser = QueryTraverser.newQueryTraverser()
                .schema(executionContext.getGraphQLSchema())
                .document(executionContext.getDocument())
                .operationName(executionContext.getOperationDefinition().getName())
                .variables(executionContext.getVariables())
                .build();

we have to move the variable coercing code into this so that we can do the defaulting as required

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Can I give a default value like this to avoid null pointer ...
None of the code in your sample would cause an NPE, no matter if you initialise the attribute owner with the empty String,...
Read more >
How to deal with NullPointerException in Java with Examples
In Java reference variable points to object created in heap but when you create a reference variable of type object by default its...
Read more >
Hibernate ORM 5.4.33.Final User Guide - Red Hat on GitHub
Default value for a database column; 4.5. ... HQL syntax for INSERT; 12.3.3. ... the hibernate.implicit_naming_strategy configuration setting which accepts:.
Read more >
Does not evaluate Terraform null variable default values #651
Null in Terraform is the equivalent of having the attribute being set to that value as absent. I believe this is causing false...
Read more >
How to set a default value to a Variable by judgin... - ServiceNow
Solved: We make our support page by the Record Producer. I want to set a different default value to a Variable per URL-parameter....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found