From c8405481c96128b4713080d3ea1a2664a57b76f3 Mon Sep 17 00:00:00 2001 From: Tiziano Pessa Date: Wed, 20 Oct 2021 23:53:14 +0200 Subject: [PATCH] fix(#736): make exception handlers work with Spring proxies --- .../error/GraphQLErrorHandlerFactory.java | 2 ++ .../error/GraphQLErrorHandlerFactoryTest.java | 21 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/graphql-kickstart-spring-support/src/main/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactory.java b/graphql-kickstart-spring-support/src/main/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactory.java index d31e44fb..87689b56 100644 --- a/graphql-kickstart-spring-support/src/main/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactory.java +++ b/graphql-kickstart-spring-support/src/main/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactory.java @@ -9,6 +9,7 @@ import java.util.Arrays; import java.util.List; import lombok.extern.slf4j.Slf4j; +import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ApplicationContext; @@ -47,6 +48,7 @@ private List scanForExceptionHandlers( return emptyList(); } return Arrays.stream(objClz.getDeclaredMethods()) + .map(method -> AopUtils.getMostSpecificMethod(method, objClz)) .filter(ReflectiveMethodValidator::isGraphQLExceptionHandler) .map(method -> withReflection(context.getBean(name), method)) .collect(toList()); diff --git a/graphql-kickstart-spring-support/src/test/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactoryTest.java b/graphql-kickstart-spring-support/src/test/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactoryTest.java index edf1f475..cd2465be 100644 --- a/graphql-kickstart-spring-support/src/test/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactoryTest.java +++ b/graphql-kickstart-spring-support/src/test/java/graphql/kickstart/spring/error/GraphQLErrorHandlerFactoryTest.java @@ -12,6 +12,7 @@ import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -29,13 +30,14 @@ public void setup() { Mockito.when(applicationContext.getBeanFactory()).thenReturn(beanFactory); Mockito.when(beanFactory.getBeanDefinitionNames()).thenReturn(new String[] {"Test"}); Mockito.when(applicationContext.containsBean("Test")).thenReturn(true); - Mockito.doReturn(TestClass.class).when(applicationContext).getType("Test"); errorHandlerFactory = new GraphQLErrorHandlerFactory(); } @Test void createFindsCollectionHandler() { + Mockito.doReturn(TestClass.class).when(applicationContext).getType("Test"); + GraphQLErrorHandler handler = errorHandlerFactory.create(applicationContext, true); assertThat(handler).isInstanceOf(GraphQLErrorFromExceptionHandler.class); GraphQLErrorFromExceptionHandler errorHandler = (GraphQLErrorFromExceptionHandler) handler; @@ -44,6 +46,23 @@ void createFindsCollectionHandler() { .isNotEmpty(); } + @Test + void createFindsExceptionHandlerEvenIfProxy() { + Mockito.doReturn(proxyTestClass()).when(applicationContext).getType("Test"); + + GraphQLErrorHandler handler = errorHandlerFactory.create(applicationContext, true); + assertThat(handler).isInstanceOf(GraphQLErrorFromExceptionHandler.class); + GraphQLErrorFromExceptionHandler errorHandler = (GraphQLErrorFromExceptionHandler) handler; + assertThat(errorHandler.getFactories()) + .as("handler.factories should not be empty") + .isNotEmpty(); + } + + private Class proxyTestClass() { + TestClass proxy = (TestClass) new ProxyFactory(new TestClass()).getProxy(); + return proxy.getClass(); + } + public static class TestClass { @ExceptionHandler(IllegalArgumentException.class)