Skip to content

Prevent loadbalancer filter to wrap exception into RuntimeException#4020

Merged
ryanjbaxter merged 3 commits intospring-cloud:mainfrom
ComputerDaddyGuy:mvc-lb-no-runtimeexception-wrap
Apr 15, 2026
Merged

Prevent loadbalancer filter to wrap exception into RuntimeException#4020
ryanjbaxter merged 3 commits intospring-cloud:mainfrom
ComputerDaddyGuy:mvc-lb-no-runtimeexception-wrap

Conversation

@ComputerDaddyGuy
Copy link
Copy Markdown
Contributor

@ComputerDaddyGuy ComputerDaddyGuy commented Dec 13, 2025

Current behavior

  • In order to allow loadbalancer lifecycle processors to handle failed requests, the lb filter catches any Exception thrown from subsequent filters. After processing, the exception is rethrown but wrapped into a RuntimeException
  • This wrap is (I suppose) originally due to usage of lambda, which does not allow to throw checked exceptions.
return (request, next) -> {
	// ...
	try {
		// Call subsequent filters
	}
	catch (Exception e) {
		supportedLifecycleProcessors.forEach(...); // Handle CompletionContext.Status.FAILED
		throw new RuntimeException(e); // <-- wrap and rethrow
	}
};

Issue

  • Wrapping into a RuntimeException prevents error handlers to catch the original exception
var builder = RouterFunctions.route();

// Not working because of RuntimeException wrap
builder = builder.onError(MyCustomException.class::isInstance, (ex, request) -> ...);

// Custom exception is catched here
builder = builder.onError(_ -> true, (ex, request) -> ...);

Proposed solution in this PR

  • The lb filter has been adapted to use an anonymous class instead of a lambda
  • The original exception is rethrown as is, without any change or wrap
  • A test has been added to ensure the lb filter does not wrap the original exception

Signed-off-by: Samuel SCHNEGG <samuel.schnegg@gmail.com>
@ComputerDaddyGuy
Copy link
Copy Markdown
Contributor Author

Any chance that maybe @ryanjbaxter or @spencergibb (or any one else) review this PR? Is it missing something, or maybe should I abandon it?
Thank you in advance!

@spencergibb
Copy link
Copy Markdown
Member

Please be patient

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Spring Cloud Gateway Server MVC load balancer (lb) filter so that exceptions from downstream filters are rethrown without being wrapped in a RuntimeException, enabling router error handlers to match on the original exception type.

Changes:

  • Refactors the lb(...) filter implementation to rethrow the original exception instead of wrapping it.
  • Adds an integration test route and assertion verifying the original exception type/message are preserved.
  • Introduces a test-only filter chain that captures exception details into response headers for verification.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
spring-cloud-gateway-server-webmvc/src/main/java/org/springframework/cloud/gateway/server/mvc/filter/LoadBalancerFilterFunctions.java Stops wrapping downstream exceptions in RuntimeException and rethrows the original exception after lifecycle completion processing.
spring-cloud-gateway-server-webmvc/src/test/java/org/springframework/cloud/gateway/server/mvc/ServerMvcIntegrationTests.java Adds a new integration test and router function to verify exceptions are not wrapped by the load balancer filter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Signed-off-by: Samuel SCHNEGG <samuel.schnegg@gmail.com>
Signed-off-by: Samuel SCHNEGG <samuel.schnegg@gmail.com>
@ryanjbaxter ryanjbaxter merged commit 8ef3612 into spring-cloud:main Apr 15, 2026
2 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in 2025.1.2 Apr 15, 2026
@github-project-automation github-project-automation Bot moved this to Done in 2025.0.3 Apr 15, 2026
@github-project-automation github-project-automation Bot moved this to Todo in 2025.1.2 Apr 15, 2026
@ryanjbaxter ryanjbaxter added this to the 4.3.5 milestone Apr 15, 2026
@ryanjbaxter
Copy link
Copy Markdown
Contributor

I also cherrypicked this into the 4.3.x branch 0420992

@ComputerDaddyGuy
Copy link
Copy Markdown
Contributor Author

Thank you! ☺️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done
Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants