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..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 @@ -36,8 +36,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 +49,7 @@ * * @author Christian Tzolov * @author SriVarshan P + * @author Seunggyu Lee */ @AutoConfiguration @ConditionalOnClass(RetryUtils.class) @@ -58,9 +61,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 +75,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 + 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