diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java index c6f3ce5ab7..84eb49c76a 100644 --- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java +++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMapping.java @@ -131,24 +131,18 @@ protected Mono 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()); } diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingTests.java index 2ee776c13d..2c5834a50b 100644 --- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingTests.java +++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/handler/RoutePredicateHandlerMappingTests.java @@ -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(); @@ -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()); @@ -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() {