diff --git a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java index 8d518a52..1bbbd47f 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolver.java @@ -42,6 +42,7 @@ import org.springframework.graphql.data.method.annotation.GraphQlExceptionHandle import org.springframework.graphql.execution.DataFetcherExceptionResolver; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -168,22 +169,24 @@ final class AnnotatedControllerExceptionResolver { Object controllerOrAdvice = null; MethodHolder methodHolder = null; + Class controllerType = null; if (controller != null) { - MethodResolver methodResolver = this.controllerCache.get(controller.getClass()); + controllerType = ClassUtils.getUserClass(controller.getClass()); + MethodResolver methodResolver = this.controllerCache.get(controllerType); if (methodResolver != null) { controllerOrAdvice = controller; methodHolder = methodResolver.resolveMethod(ex); } else if (logger.isWarnEnabled()) { - logger.warn("No registration for controller type: " + controller.getClass().getName()); + logger.warn("No registration for controller type: " + controllerType.getName()); } } if (methodHolder == null) { for (Map.Entry entry : this.controllerAdviceCache.entrySet()) { ControllerAdviceBean advice = entry.getKey(); - if (controller == null || advice.isApplicableToBeanType(controller.getClass())) { + if (controller == null || advice.isApplicableToBeanType(controllerType)) { methodHolder = entry.getValue().resolveMethod(ex); if (methodHolder != null) { controllerOrAdvice = advice.resolveBean(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java index 98b8cb4d..a19a824d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/AnnotatedControllerExceptionResolverTests.java @@ -26,6 +26,8 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.aop.target.SingletonTargetSource; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.StaticApplicationContext; @@ -125,6 +127,20 @@ public class AnnotatedControllerExceptionResolverTests { exceptionResolver().registerController(InvalidReturnTypeController.class)); } + @Test // gh-710 + void controllerWithProxy() { + TestController controller = new TestController(); + AnnotatedControllerExceptionResolver resolver = exceptionResolver(); + resolver.registerController(controller.getClass()); + + Exception ex = new IllegalArgumentException("Bad input"); + Object proxy = ProxyFactory.getProxy(new SingletonTargetSource(controller)); + List actual = resolver.resolveException(ex, this.environment, proxy).block(); + + assertThat(actual).hasSize(1); + assertThat(actual.get(0).getMessage()).isEqualTo("handleToSingleError: Bad input"); + } + private void testResolve(Throwable ex, TestController controller, List expected) { AnnotatedControllerExceptionResolver resolver = exceptionResolver(); @@ -156,7 +172,7 @@ public class AnnotatedControllerExceptionResolverTests { @SuppressWarnings("unused") @Controller - private static class TestController { + static class TestController { @GraphQlExceptionHandler GraphQLError handleToSingleError(IllegalArgumentException ex) {