2

I'm writing a API Gateway app built using Spring Cloud Gateway MVC. I'm using a custom CircuitBreaker filter that can timeout when backend requests take too long.

I'm seeing that when the request timeout...I'm not able to handle the failures in a graceful way by sending a JSON format response back to the client.

I have custom ControllerAdvice beans with ExceptionHandler methods that never seem to intercept any of the failures within the Gateway MVC filers. ExceptionHandling works perfectly when the failure happens outside the GatewayMVC filters like failure to find a matching route etc.

Are ControllerAdvice beans expected to handle GatewayFilter failures? We have RouterFunctions not MVC controllers anymore.

Any guidance on ExceptionHandling for SpringGatewayMVC?

Thanks for your help.

2
  • Did you find a solution for this? I am having the same issue, @ControllerAdvice do not work for MVC routes created with non reactive RouterFunction. Commented Jun 6, 2024 at 4:18
  • @Thiago: I encountered the same issue today. Unfortunately, there is currently no support for Spring Cloud Gateway MVC version. You can take a look at my implementation, which is based on the author's suggestion. Thanks. Commented Jun 11, 2024 at 16:35

3 Answers 3

0

What I found was ControllerAdvice beans don't work and never meant to work with Spring MVC.fn functions. The was I was able to handle exceptions is with custom onError handler functions.

Sign up to request clarification or add additional context in comments.

Comments

0

The ControllerAdvice bean wont work on the filter part ,Because this controller advice will trigger when the exception thrown by the controller

Comments

0

To write a Filtering Handler Function programmatically:

https://docs.spring.io/spring-framework/reference/web/webmvc-functional.html#webmvc-fn-handler-filter-function
https://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway-server-mvc/writing-custom-predicates-and-filters.html

In our application, we use a declarative approach, so here’s what I did:

Step 1: Create a custom ExceptionHandler:

public interface CustomGatewayFilterFunctions {
        @Shortcut
        static HandlerFilterFunction<ServerResponse, ServerResponse> handleAuthenticationException() {
            return (request, next) -> {
                
                // Your exception handler implementation 
                // example: if not ok then return return ServerResponse.status(UNAUTHORIZED).build();


                return response;
            };
        }

        class CustomGatewayFilter implements org.springframework.cloud.gateway.server.mvc.filter.FilterSupplier {

            @Override
            public Collection<Method> get() {
                return Arrays.asList(CustomGatewayFilterFunctions.class.getMethods());
            }

        }
    }

Step 2: In your resources/META-INF/spring.factories file, define your handler (create the file if it doesn't already exist).

# Override spring-cloud-gateway-server-mvc-4.1.0.jar!\META-INF\spring.factories
# to add Error Handler
org.springframework.cloud.gateway.server.mvc.filter.FilterSupplier=\
  org.springframework.cloud.gateway.server.mvc.filter.Bucket4jFilterFunctions.FilterSupplier,\
  org.springframework.cloud.gateway.server.mvc.filter.CircuitBreakerFilterFunctions.FilterSupplier,\
  org.springframework.cloud.gateway.server.mvc.filter.FilterFunctions.FilterSupplier,\
  your.path.to.CustomGatewayFilterFunctions.CustomGatewayFilter

Step 3: In your gateway declaration add you HandleAuthenticationException:

spring.cloud.gateway.mvc.routes[0].id=your_route
// Other declaration
spring.cloud.gateway.mvc.routes[0].filters[0]=HandleAuthenticationException

Then you should be able to debug your CustomGatewayFilterFunctions and add your desired behavior. If you want to know more, you can debug the method

GatewayMvcPropertiesBeanDefinitionRegistrar.getRouterFunction   
        -> Section // translate filters

Please note that I am using spring-cloud-gateway-server-mvc:4.1.0, so your implementation might differ slightly from this one, but the core concept remains the same.

For more detail, see Github ticket about @ControllerAdvice and @ExceptionHandler https://github.com/spring-cloud/spring-cloud-gateway/issues/3335

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.