From 635dad7b1fd5732ed8df2f3b9a8aa823daaa1e29 Mon Sep 17 00:00:00 2001 From: Seunggyu Lee Date: Thu, 9 Oct 2025 17:16:02 +0900 Subject: [PATCH 1/2] #4567: Enhances retry configuration for network errors Extends the retry configuration to include `ResourceAccessException` and, if available, `WebClientRequestException` to handle transient network errors during AI service calls more effectively. This improves the resilience of the application when interacting with potentially unstable AI services. Signed-off-by: Seunggyu Lee --- .../SpringAiRetryAutoConfiguration.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java index 36d212c8d8a..0bf541b4354 100644 --- a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java +++ b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java @@ -21,7 +21,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.ai.retry.NonTransientAiException; import org.springframework.ai.retry.RetryUtils; import org.springframework.ai.retry.TransientAiException; @@ -36,8 +35,10 @@ import org.springframework.retry.RetryContext; import org.springframework.retry.RetryListener; import org.springframework.retry.support.RetryTemplate; +import org.springframework.retry.support.RetryTemplateBuilder; import org.springframework.util.CollectionUtils; import org.springframework.util.StreamUtils; +import org.springframework.web.client.ResourceAccessException; import org.springframework.web.client.ResponseErrorHandler; /** @@ -47,6 +48,7 @@ * * @author Christian Tzolov * @author SriVarshan P + * @author Seunggyu Lee */ @AutoConfiguration @ConditionalOnClass(RetryUtils.class) @@ -58,9 +60,10 @@ public class SpringAiRetryAutoConfiguration { @Bean @ConditionalOnMissingBean public RetryTemplate retryTemplate(SpringAiRetryProperties properties) { - return RetryTemplate.builder() + RetryTemplateBuilder builder = RetryTemplate.builder() .maxAttempts(properties.getMaxAttempts()) .retryOn(TransientAiException.class) + .retryOn(ResourceAccessException.class) .exponentialBackoff(properties.getBackoff().getInitialInterval(), properties.getBackoff().getMultiplier(), properties.getBackoff().getMaxInterval()) .withListener(new RetryListener() { @@ -71,8 +74,21 @@ public void onError(RetryContext context, RetryCallback logger.warn("Retry error. Retry count: {}, Exception: {}", context.getRetryCount(), throwable.getMessage(), throwable); } - }) - .build(); + }); + + // Optionally add WebFlux pre-response network errors if present without hard dependency + try { + Class webClientRequestEx = Class + .forName("org.springframework.web.reactive.function.client.WebClientRequestException"); + @SuppressWarnings("unchecked") + Class exClass = (Class) webClientRequestEx; + builder.retryOn(exClass); + } + catch (ClassNotFoundException ignore) { + // WebFlux not on classpath; skip + } + + return builder.build(); } @Bean From 9d1eb67617a222d62d41bc33284ea17f7993dc7a Mon Sep 17 00:00:00 2001 From: Seunggyu Lee Date: Thu, 9 Oct 2025 19:49:58 +0900 Subject: [PATCH 2/2] apply format Signed-off-by: Seunggyu Lee --- .../retry/autoconfigure/SpringAiRetryAutoConfiguration.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java index 0bf541b4354..3edc0ed25af 100644 --- a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java +++ b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; + import org.springframework.ai.retry.NonTransientAiException; import org.springframework.ai.retry.RetryUtils; import org.springframework.ai.retry.TransientAiException; @@ -76,10 +77,10 @@ public void onError(RetryContext context, RetryCallback } }); - // Optionally add WebFlux pre-response network errors if present without hard dependency + // Optionally add WebFlux pre-response network errors if present try { Class webClientRequestEx = Class - .forName("org.springframework.web.reactive.function.client.WebClientRequestException"); + .forName("org.springframework.web.reactive.function.client.WebClientRequestException"); @SuppressWarnings("unchecked") Class exClass = (Class) webClientRequestEx; builder.retryOn(exClass);