CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry

Spring Boot auto-configuration for AI retry capabilities with exponential backoff and intelligent HTTP error handling

Overview
Eval results
Files

quick-start.mddocs/guides/

Quick Start Guide

This guide walks you through setting up and using Spring AI Retry Auto Configuration in your Spring Boot application.

Prerequisites

  • Spring Boot 2.7+ or 3.0+
  • Java 17+
  • Maven or Gradle build tool

Step 1: Add Dependency

Maven

Add to your pom.xml:

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-autoconfigure-retry</artifactId>
    <version>1.1.2</version>
</dependency>

Gradle

Add to your build.gradle:

implementation 'org.springframework.ai:spring-ai-autoconfigure-retry:1.1.2'

Step 2: Understand Auto-Configuration

Once the dependency is added, Spring Boot automatically configures:

  1. RetryTemplate bean - Handles retry logic with exponential backoff
  2. ResponseErrorHandler bean - Classifies HTTP errors

No explicit configuration required! The beans are ready to use.

Step 3: Inject and Use RetryTemplate

Basic Injection

import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Service;

@Service
public class AiService {
    
    private final RetryTemplate retryTemplate;
    
    // Constructor injection
    public AiService(RetryTemplate retryTemplate) {
        this.retryTemplate = retryTemplate;
    }
    
    public String callAiModel(String prompt) {
        return retryTemplate.execute(context -> {
            // Your AI API call here
            return performAiApiCall(prompt);
        });
    }
    
    private String performAiApiCall(String prompt) {
        // Implementation
        return "AI response";
    }
}

With RestTemplate

import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.stereotype.Service;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RestConfig {
    
    @Bean
    public RestTemplate aiRestTemplate(ResponseErrorHandler errorHandler) {
        RestTemplate template = new RestTemplate();
        // Auto-configured error handler
        template.setErrorHandler(errorHandler);
        return template;
    }
}

@Service
public class AiService {
    
    private final RetryTemplate retryTemplate;
    private final RestTemplate restTemplate;
    
    public AiService(RetryTemplate retryTemplate, RestTemplate aiRestTemplate) {
        this.retryTemplate = retryTemplate;
        this.restTemplate = aiRestTemplate;
    }
    
    public String getCompletion(String prompt) {
        return retryTemplate.execute(context -> {
            // RestTemplate uses auto-configured error handler
            // Throws TransientAiException or NonTransientAiException
            return restTemplate.postForObject(
                "https://api.example.com/complete",
                prompt,
                String.class
            );
        });
    }
}

Step 4: Configure Retry Behavior (Optional)

Create application.properties or application.yml to customize:

application.properties

# Maximum retry attempts
spring.ai.retry.max-attempts=10

# HTTP codes to always retry
spring.ai.retry.on-http-codes=429,503

# HTTP codes to never retry
spring.ai.retry.exclude-on-http-codes=401,403

# Exponential backoff settings
spring.ai.retry.backoff.initial-interval=2s
spring.ai.retry.backoff.multiplier=5
spring.ai.retry.backoff.max-interval=3m

application.yml

spring:
  ai:
    retry:
      max-attempts: 10
      on-http-codes:
        - 429
        - 503
      exclude-on-http-codes:
        - 401
        - 403
      backoff:
        initial-interval: 2s
        multiplier: 5
        max-interval: 3m

Step 5: Handle Exceptions

Basic Exception Handling

import org.springframework.ai.retry.TransientAiException;
import org.springframework.ai.retry.NonTransientAiException;

public String callWithErrorHandling(String prompt) {
    try {
        return retryTemplate.execute(context -> callApi(prompt));
    } catch (TransientAiException e) {
        // All retries exhausted - temporary issue
        log.error("Service temporarily unavailable: {}", e.getMessage());
        return "Service unavailable. Please try again later.";
    } catch (NonTransientAiException e) {
        // Permanent failure - configuration/auth issue
        log.error("Service configuration error: {}", e.getMessage());
        return "Service error. Please check your configuration.";
    }
}

With Recovery Callback

public String callWithFallback(String prompt) {
    return retryTemplate.execute(
        // Retry callback
        context -> callApi(prompt),
        // Recovery callback - invoked when all retries fail
        context -> {
            log.warn("Using fallback after {} attempts", context.getRetryCount());
            return "Fallback response - service temporarily unavailable";
        }
    );
}

Step 6: Verify Configuration

Check Beans Are Loaded

import org.springframework.boot.CommandLineRunner;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.stereotype.Component;

@Component
public class RetryConfigVerifier implements CommandLineRunner {
    
    private final RetryTemplate retryTemplate;
    private final ResponseErrorHandler errorHandler;
    
    public RetryConfigVerifier(RetryTemplate retryTemplate, 
                               ResponseErrorHandler errorHandler) {
        this.retryTemplate = retryTemplate;
        this.errorHandler = errorHandler;
    }
    
    @Override
    public void run(String... args) {
        System.out.println("✓ RetryTemplate bean loaded: " + retryTemplate);
        System.out.println("✓ ResponseErrorHandler bean loaded: " + errorHandler);
    }
}

Test Retry Behavior

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.ai.retry.TransientAiException;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
class RetryTest {
    
    @Autowired
    private RetryTemplate retryTemplate;
    
    @Test
    void testRetryOnTransientError() {
        AtomicInteger attempts = new AtomicInteger(0);
        
        String result = retryTemplate.execute(context -> {
            int attempt = attempts.incrementAndGet();
            if (attempt < 3) {
                throw new TransientAiException("Transient error");
            }
            return "success";
        });
        
        assertThat(result).isEqualTo("success");
        assertThat(attempts.get()).isEqualTo(3);
    }
}

Common Patterns

Pattern 1: Simple Retry

public String simpleRetry() {
    return retryTemplate.execute(context -> callApi());
}

Pattern 2: Retry with Context

public String retryWithContext() {
    return retryTemplate.execute(context -> {
        int attemptNumber = context.getRetryCount() + 1;
        log.info("Attempt {} of {}", attemptNumber, maxAttempts);
        return callApi();
    });
}

Pattern 3: Retry with Fallback

public String retryWithFallback() {
    return retryTemplate.execute(
        context -> callApi(),
        context -> getFallbackResponse()
    );
}

Pattern 4: Custom Exception Handling

public String customExceptionHandling() {
    try {
        return performOperation();
    } catch (IOException e) {
        // Network error - transient
        throw new TransientAiException("Network error", e);
    } catch (AuthException e) {
        // Auth error - non-transient
        throw new NonTransientAiException("Authentication failed", e);
    }
}

Next Steps

  • Configuration: Learn about advanced configuration options
  • Examples: See real-world scenarios
  • Reference: Explore the complete API reference

Troubleshooting

Issue: Beans Not Auto-Configured

Symptom: NoSuchBeanDefinitionException for RetryTemplate

Solution: Ensure dependency is on classpath and RetryUtils class is available:

// Verify RetryUtils is available
import org.springframework.ai.retry.RetryUtils;

Issue: Retries Not Working

Symptom: No retries happening on errors

Solution: Ensure you're throwing TransientAiException:

// Correct - will retry
throw new TransientAiException("Error");

// Incorrect - won't retry
throw new RuntimeException("Error");

Issue: Too Many Retries

Symptom: Application hangs with long retry delays

Solution: Reduce max-attempts and backoff intervals:

spring.ai.retry.max-attempts=3
spring.ai.retry.backoff.max-interval=5s

Quick Reference

Import Statements

// Core classes
import org.springframework.retry.support.RetryTemplate;
import org.springframework.web.client.ResponseErrorHandler;

// Exceptions
import org.springframework.ai.retry.TransientAiException;
import org.springframework.ai.retry.NonTransientAiException;

// Configuration
import org.springframework.ai.retry.autoconfigure.SpringAiRetryProperties;

// Utilities
import org.springframework.ai.retry.RetryUtils;

Default Values

PropertyDefaultDescription
max-attempts10Total retry attempts
on-client-errorsfalseRetry 4xx errors
initial-interval2sFirst retry delay
multiplier5Backoff multiplier
max-interval3mMax retry delay

HTTP Status Defaults

CodeBehaviorReason
4xxNo retryClient error
5xxRetryServer error
429Retry (if configured)Rate limit
401, 403No retry (if configured)Auth error
tessl i tessl/maven-org-springframework-ai--spring-ai-autoconfigure-retry@1.1.1

docs

index.md

tile.json