Skip to content

Commit c03a485

Browse files
committed
Auto-config: Retries for network exceptions
Extends the retry configuration to include ResourceAccessException and, if available, WebClientRequestException to handle transient network errors during AI service calls more effectively. Fixes #4567 Signed-off-by: Seunggyu Lee <dltmdrb98@gmail.com>
1 parent e673935 commit c03a485

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@
3636
import org.springframework.retry.RetryContext;
3737
import org.springframework.retry.RetryListener;
3838
import org.springframework.retry.support.RetryTemplate;
39+
import org.springframework.retry.support.RetryTemplateBuilder;
3940
import org.springframework.util.CollectionUtils;
4041
import org.springframework.util.StreamUtils;
42+
import org.springframework.web.client.ResourceAccessException;
4143
import org.springframework.web.client.ResponseErrorHandler;
4244

4345
/**
@@ -47,20 +49,22 @@
4749
*
4850
* @author Christian Tzolov
4951
* @author SriVarshan P
52+
* @author Seunggyu Lee
5053
*/
5154
@AutoConfiguration
5255
@ConditionalOnClass(RetryUtils.class)
53-
@EnableConfigurationProperties(SpringAiRetryProperties.class)
56+
@EnableConfigurationProperties({ SpringAiRetryProperties.class })
5457
public class SpringAiRetryAutoConfiguration {
5558

5659
private static final Logger logger = LoggerFactory.getLogger(SpringAiRetryAutoConfiguration.class);
5760

5861
@Bean
5962
@ConditionalOnMissingBean
6063
public RetryTemplate retryTemplate(SpringAiRetryProperties properties) {
61-
return RetryTemplate.builder()
64+
RetryTemplateBuilder builder = RetryTemplate.builder()
6265
.maxAttempts(properties.getMaxAttempts())
6366
.retryOn(TransientAiException.class)
67+
.retryOn(ResourceAccessException.class)
6468
.exponentialBackoff(properties.getBackoff().getInitialInterval(), properties.getBackoff().getMultiplier(),
6569
properties.getBackoff().getMaxInterval())
6670
.withListener(new RetryListener() {
@@ -71,8 +75,21 @@ public <T, E extends Throwable> void onError(RetryContext context, RetryCallback
7175
logger.warn("Retry error. Retry count: {}, Exception: {}", context.getRetryCount(),
7276
throwable.getMessage(), throwable);
7377
}
74-
})
75-
.build();
78+
});
79+
80+
// Optionally add WebFlux pre-response network errors if present
81+
try {
82+
Class<?> webClientRequestEx = Class
83+
.forName("org.springframework.web.reactive.function.client.WebClientRequestException");
84+
@SuppressWarnings("unchecked")
85+
Class<? extends Throwable> exClass = (Class<? extends Throwable>) webClientRequestEx;
86+
builder.retryOn(exClass);
87+
}
88+
catch (ClassNotFoundException ignore) {
89+
// WebFlux not on classpath; skip
90+
}
91+
92+
return builder.build();
7693
}
7794

7895
@Bean

0 commit comments

Comments
 (0)