AnnotatedControllerExceptionResolver handles proxy class

Closes gh-710
This commit is contained in:
rstoyanchev
2023-05-31 15:46:26 +01:00
parent fcb7f941c3
commit ee432a8c21
2 changed files with 23 additions and 4 deletions

View File

@@ -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<ControllerAdviceBean, MethodResolver> 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();

View File

@@ -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<GraphQLError> 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<String> 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) {