Skip to content

RoutePredicateHandlerMapping doesn't hanle Mono errors properly #3808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
46c5427
fix error handling for async predicate
May 16, 2025
30e8a03
Add tests for LoadBalancerHandlerConfiguration (#3779)
OlgaMaciaszek May 20, 2025
ff35732
Adds spring-boot-properties-migrator to server starters.
spencergibb May 20, 2025
0b5ff0d
formatting
spencergibb May 20, 2025
de8f310
Fix improper encoding of '+' in query parameter values
raccoonback May 14, 2025
8e946c6
Update maven.yml
spencergibb May 22, 2025
568a59d
Migrate server-webmvc properties to new namespace
spencergibb May 22, 2025
26dac78
Attempt to get tests to pass in github actions
spencergibb May 22, 2025
f695d7f
Moves github action system property to a profile
spencergibb May 22, 2025
7af0761
feat(gateway-filter): add SetRequestUri gateway filter
stepancar Apr 13, 2025
8f22210
fix(*): remove unnecessary exception according review comments
stepancar May 20, 2025
48439a9
fix(*): remove unnecessary exception according review comments
stepancar May 20, 2025
d7cc3cd
fix(*): fix disable builtin filter
stepancar May 22, 2025
0a4dbc5
add new config for AddResponseHeaderGatewayFilterFactory
JoeCqupt May 19, 2025
057bb48
update docs
JoeCqupt May 20, 2025
01238ce
avoid breaking changes
JoeCqupt May 23, 2025
2610896
Fix improper encoding of '+' in query parameter values when rewrite q…
raccoonback May 15, 2025
6f82044
Bumping versions
spring-builds May 24, 2025
c255b29
Fix runtime hints for native images. (#3806)
OlgaMaciaszek May 27, 2025
c82123d
Add documentation for routing to functions (#3767)
olegz May 27, 2025
42c8534
Merge branch 'spring-cloud:main' into main
taxone May 27, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,21 @@ void rewritePlusSignRequestParameter() {
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo=replacement%2B");
}

@Test
void rewritePlusSignRequestParameter() {
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
.param("foo", "bar")
.param("baz", "qux")
.buildRequest(null);

ServerRequest request = ServerRequest.create(servletRequest, Collections.emptyList());

ServerRequest result = BeforeFilterFunctions.rewriteRequestParameter("foo", "replacement+").apply(request);

assertThat(result.param("foo")).isPresent().hasValue("replacement+");
assertThat(result.uri().toString()).hasToString("http://localhost/path?baz=qux&foo=replacement%2B");
}

@Test
void rewriteRequestParameterWithEncodedRemainParameters() {
MockHttpServletRequest servletRequest = MockMvcRequestBuilders.get("http://localhost/path")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,24 +131,18 @@ protected Mono<Route> lookupRoute(ServerWebExchange exchange) {
return this.routeLocator.getRoutes().filterWhen(route -> {
// add the current route we are testing
exchange.getAttributes().put(GATEWAY_PREDICATE_ROUTE_ATTR, route.getId());
try {
return route.getPredicate().apply(exchange);
}
catch (Exception e) {

return Mono.defer(() -> Mono.from(route.getPredicate().apply(exchange))).onErrorResume(e -> {
logger.error("Error applying predicate for route: " + route.getId(), e);
}
return Mono.just(false);
})
.next()
// TODO: error handling
.map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("Route matched: " + route.getId());
}
validateRoute(route, exchange);
return route;
return Mono.just(false);
});

}).next().map(route -> {
if (logger.isDebugEnabled()) {
logger.debug("Route matched: " + route.getId());
}
validateRoute(route, exchange);
return route;
});
/*
* TODO: trace logging if (logger.isTraceEnabled()) {
* logger.trace("RouteDefinition did not match: " + routeDefinition.getId()); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ public void lookupRouteFromAsyncPredicates(CapturedOutput capturedOutput) {
.uri("http://localhost")
.asyncPredicate(swe -> Mono.just(boom1()))
.build();
Route routeMonoError = Route.async()
.id("routeMonoError")
.uri("http://localhost")
.asyncPredicate(swe -> Mono.error(new IllegalStateException("boom3")))
.build();
Route routeFail = Route.async().id("routeFail").uri("http://localhost").asyncPredicate(swe -> {
throw new IllegalStateException("boom2");
}).build();
Expand All @@ -82,7 +87,8 @@ public void lookupRouteFromAsyncPredicates(CapturedOutput capturedOutput) {
.uri("http://localhost")
.asyncPredicate(swe -> Mono.just(true))
.build();
RouteLocator routeLocator = () -> Flux.just(routeFalse, routeError, routeFail, routeTrue).hide();
RouteLocator routeLocator = () -> Flux.just(routeFalse, routeError, routeMonoError, routeFail, routeTrue)
.hide();
RoutePredicateHandlerMapping mapping = new RoutePredicateHandlerMapping(null, routeLocator,
new GlobalCorsProperties(), new MockEnvironment());

Expand All @@ -95,6 +101,9 @@ public void lookupRouteFromAsyncPredicates(CapturedOutput capturedOutput) {

assertThat(capturedOutput.getOut().contains("Error applying predicate for route: routeFail")).isTrue();
assertThat(capturedOutput.getOut().contains("java.lang.IllegalStateException: boom2")).isTrue();

assertThat(capturedOutput.getOut().contains("Error applying predicate for route: routeMonoError")).isTrue();
assertThat(capturedOutput.getOut().contains("java.lang.IllegalStateException: boom3")).isTrue();
}

boolean boom1() {
Expand Down