graphql-spring-boot
graphql-spring-boot copied to clipboard
Custom exception handlers are not detected when using Spring Cloud Stream
Describe the bug Custom exception handlers are not detected whenever Spring Cloud Stream with the Solace PubSub+ binder is on the classpath.
Let's say we have two custom exceptions, Foo
and Bar
, along with the following exception handler:
@Component
public class GraphQLExceptionHandler {
@ExceptionHandler(Foo.class)
public ThrowableGraphQLError handle(Foo e) {
return new ThrowableGraphQLError(e);
}
@ExceptionHandler(Throwable.class)
public ThrowableGraphQLError handle(Throwable e) {
return new ThrowableGraphQLError(e, "Internal Server Error(s) while executing query");
}
}
Exceptions of type Foo
should then have their messages displayed to the user directly, but any other exception type should be hidden behind a generic error message before being shown to the user. This works fine, until the following two dependencies are added to the project:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>com.solace.spring.cloud</groupId>
<artifactId>spring-cloud-starter-stream-solace</artifactId>
</dependency>
After a lot of debugging I've been able to find one clue as to what's going wrong. The ApplicationContext
instance that gets passed to com.nictas.graphql.curious.dolphin.graphql.GraphQLExceptionHandler
is different depending on whether the Maven dependencies mentioned above are on the classpath or not:
-
org.springframework.context.annotation.AnnotationConfigApplicationContext
if they are; An important thing to note is that theAnnotationConfigApplicationContext
instance does NOT contain the custom exception handler bean (hence the issue). That's because the bean is in a different application context (theAnnotationConfigServletWebServerApplicationContext
instance that still exists). The problem seems to come from the fact that a second application context is created whenever Spring Cloud Stream is on the classpath and theGraphQLExceptionHandler
is called with the wrong one. -
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
if they are NOT;
I've tried using the latest versions of Spring and GraphQL kickstart, but nothing solves the issue.
To Reproduce I've created a small project that can be used to reproduce the problem: https://github.com/nictas/graphql-curious-dolphin Just follow the instructions in its README.
Desktop:
- OS: Windows 10
- Browser: Google Chrome
- Version: 90.0.4430.212 (Official Build) (64-bit)
@nictas does your application.yaml contain following configuration?
graphql:
servlet:
exception-handlers-enabled: true
I had same issue after upgrading to 11.1.0 and adding exception-handlers-enabled: true
helped me
@bBellovic It does, yes: https://github.com/nictas/graphql-curious-dolphin/blob/eaf9b18b34037d051b121f06f451c9002649e276/src/main/resources/application.yaml#L6