graphql-spring-boot icon indicating copy to clipboard operation
graphql-spring-boot copied to clipboard

`ErrorHandlerSupplier` not always initialized when we first need it

Open rems opened this issue 1 year ago • 0 comments

The ErrorHandlerSupplier might not be fully initialized when we first need it.

As such, a nasty NPE might arise.

java.lang.NullPointerException: Cannot invoke "graphql.kickstart.execution.error.GraphQLErrorHandler.errorsPresent(java.util.List)" because "errorHandler" is null
	at graphql.kickstart.execution.GraphQLObjectMapper.sanitizeErrors(GraphQLObjectMapper.java:131)
	at graphql.kickstart.execution.GraphQLObjectMapper.createResultFromExecutionResult(GraphQLObjectMapper.java:140)
	at graphql.kickstart.execution.GraphQLObjectMapper.serializeResultAsBytes(GraphQLObjectMapper.java:118)
	at graphql.kickstart.servlet.SingleQueryResponseWriter.write(SingleQueryResponseWriter.java:23)
	at graphql.kickstart.servlet.HttpRequestInvokerImpl.writeResultResponse(HttpRequestInvokerImpl.java:149)
	at graphql.kickstart.servlet.HttpRequestInvokerImpl.writeErrorResponse(HttpRequestInvokerImpl.java:163)
	at graphql.kickstart.servlet.HttpRequestInvokerImpl.lambda$handleInternal$5(HttpRequestInvokerImpl.java:137)
	at java.base/java.util.concurrent.CompletableFuture.uniExceptionally(CompletableFuture.java:990)
	at java.base/java.util.concurrent.CompletableFuture.uniExceptionallyStage(CompletableFuture.java:1008)
	at java.base/java.util.concurrent.CompletableFuture.exceptionally(CompletableFuture.java:2364)
	at graphql.kickstart.servlet.HttpRequestInvokerImpl.handleInternal(HttpRequestInvokerImpl.java:135)
	at graphql.kickstart.servlet.HttpRequestInvokerImpl.handle(HttpRequestInvokerImpl.java:109)

It's a bit of a race condition when starting the app, so it's a bit tricky to provide steps to reproduce.

Before

public class GraphQLErrorStartupListener implements ApplicationListener<ApplicationReadyEvent> {

  // ... omitted for brevity

  @Override
  public void onApplicationEvent(ApplicationReadyEvent event) {
     // omitted for brevity
  }
}

Suggested

Change the type of event being listened, from ApplicationReadyEvent to ApplicationStartedEvent

public class GraphQLErrorStartupListener implements ApplicationListener<ApplicationStartedEvent> {

  // ... omitted for brevity

  @Override
  public void onApplicationEvent(ApplicationStartedEvent event) {
     // unchanged body method
  }
}

rems avatar Apr 12 '23 15:04 rems