CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-quarkus--quarkus-smallrye-fault-tolerance

Build fault-tolerant network services

Pending
Overview
Eval results
Files

fallback-strategies.mddocs/

Fallback Strategies

Alternative execution paths when primary methods fail, including custom fallback handlers, fallback methods, and exception-based fallback logic.

Capabilities

Method-based Fallback

Fallback to alternative methods in the same class with matching signatures.

@Fallback(
    fallbackMethod = "alternativeMethod",
    applyOn = {IOException.class, TimeoutException.class},
    skipOn = {IllegalArgumentException.class}
)
public ReturnType methodWithFallback(ParameterType param);

// Fallback method must have matching signature
public ReturnType alternativeMethod(ParameterType param);

Parameters

  • fallbackMethod - Name of fallback method in same class
  • applyOn - Exception types that trigger fallback (default: Throwable.class)
  • skipOn - Exception types that skip fallback (takes precedence)

Usage Example

@ApplicationScoped
public class UserService {
    
    @Inject
    ExternalUserApi externalApi;
    
    @Inject
    UserCache cache;
    
    // Primary method with cached fallback
    @Fallback(
        fallbackMethod = "getUserFromCache",
        applyOn = {ConnectException.class, TimeoutException.class}
    )
    @Timeout(5000)
    public User getUser(Long userId) throws UserNotFoundException {
        return externalApi.fetchUser(userId);
    }
    
    public User getUserFromCache(Long userId) throws UserNotFoundException {
        User cached = cache.get(userId);
        if (cached != null) {
            return cached;
        }
        throw new UserNotFoundException("User not found: " + userId);
    }
    
    // Order service with default fallback
    @Fallback(fallbackMethod = "getDefaultOrderStatus")
    public OrderStatus getOrderStatus(String orderId) throws ServiceException {
        return orderServiceClient.getStatus(orderId);
    }
    
    public OrderStatus getDefaultOrderStatus(String orderId) {
        return OrderStatus.PENDING; // Safe default
    }
}

Handler-based Fallback

Custom fallback handlers for complex fallback logic and cross-cutting concerns.

@Fallback(
    value = CustomFallbackHandler.class,
    applyOn = {IOException.class},
    skipOn = {SecurityException.class}
)
public ReturnType methodWithHandler(ParameterType param);

// Fallback handler implementation
class CustomFallbackHandler implements FallbackHandler<ReturnType> {
    public ReturnType handle(ExecutionContext context);
}

Usage Example

@ApplicationScoped
public class PaymentService {
    
    // Payment with sophisticated fallback handler
    @Fallback(value = PaymentFallbackHandler.class)
    @CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.4)
    public PaymentResult processPayment(PaymentRequest request) throws PaymentException {
        return primaryPaymentGateway.process(request);
    }
}

// Sophisticated fallback handler
public class PaymentFallbackHandler implements FallbackHandler<PaymentResult> {
    
    @Inject
    SecondaryPaymentGateway secondaryGateway;
    
    @Inject
    PaymentQueue paymentQueue;
    
    @Inject
    NotificationService notifications;
    
    @Override
    public PaymentResult handle(ExecutionContext context) {
        PaymentRequest request = (PaymentRequest) context.getParameters()[0];
        Throwable failure = context.getFailure();
        
        // Try secondary payment gateway first
        try {
            return secondaryGateway.process(request);
        } catch (Exception e) {
            // Queue for later processing
            paymentQueue.enqueue(request);
            
            // Notify customer
            notifications.notifyPaymentDelayed(request.getCustomerId());
            
            return PaymentResult.queued(request.getTransactionId());
        }
    }
}

Conditional Fallback

Fallback logic based on specific exception types and conditions.

@Fallback(
    fallbackMethod = "specificFallback",
    applyOn = {ServiceUnavailableException.class, TimeoutException.class},
    skipOn = {ValidationException.class, SecurityException.class}
)
public ReturnType conditionalFallbackMethod();

Usage Example

@ApplicationScoped
public class NotificationService {
    
    @Inject
    EmailService emailService;
    
    @Inject
    SmsService smsService;
    
    @Inject
    PushNotificationService pushService;
    
    // Email with SMS fallback for delivery issues
    @Fallback(
        fallbackMethod = "sendViaSms",
        applyOn = {MailServerException.class, DeliveryException.class},
        skipOn = {InvalidEmailException.class}
    )
    public NotificationResult sendEmail(String recipient, String message) {
        return emailService.send(recipient, message);
    }
    
    public NotificationResult sendViaSms(String recipient, String message) {
        // Convert email recipient to phone number if possible
        String phoneNumber = contactService.getPhoneNumber(recipient);
        if (phoneNumber != null) {
            return smsService.send(phoneNumber, message);
        }
        return NotificationResult.failed("No SMS fallback available");
    }
    
    // Push notification with multiple fallbacks
    @Fallback(
        fallbackMethod = "sendViaEmail",
        applyOn = {PushServiceException.class}
    )
    public NotificationResult sendPushNotification(String userId, String message) {
        return pushService.send(userId, message);
    }
    
    public NotificationResult sendViaEmail(String userId, String message) {
        String email = userService.getEmail(userId);
        try {
            return sendEmail(email, message); // This has its own fallback
        } catch (Exception e) {
            return NotificationResult.failed("All notification methods failed");
        }
    }
}

Fallback with Circuit Breaker

Combined fallback and circuit breaker patterns for comprehensive resilience.

@CircuitBreaker(requestVolumeThreshold = 10, failureRatio = 0.5)
@Fallback(fallbackMethod = "circuitBreakerFallback")
@Timeout(5000)
public ReturnType resilientMethod();

Usage Example

@ApplicationScoped
public class CatalogService {
    
    @Inject
    ExternalCatalogApi externalApi;
    
    @Inject
    CatalogCache cache;
    
    @Inject
    DefaultCatalogProvider defaultProvider;
    
    // Product catalog with circuit breaker and cached fallback
    @CircuitBreaker(
        requestVolumeThreshold = 15,
        failureRatio = 0.3,
        delay = 30000
    )
    @Fallback(fallbackMethod = "getCachedCatalog")
    @Timeout(8000)
    public ProductCatalog getProductCatalog(String category) throws CatalogException {
        return externalApi.getCatalog(category);
    }
    
    public ProductCatalog getCachedCatalog(String category) throws CatalogException {
        // Try cache first
        ProductCatalog cached = cache.get(category);
        if (cached != null && !cached.isExpired()) {
            return cached.withStaleIndicator();
        }
        
        // Fall back to default catalog
        return defaultProvider.getDefaultCatalog(category);
    }
}

Types

Fallback Core Types

// Execution context for fallback handlers
interface ExecutionContext {
    Method getMethod();
    Object[] getParameters();
    Object getTarget();
    Throwable getFailure();
    Map<String, Object> getContextData();
}

// Fallback handler interface
interface FallbackHandler<T> {
    /**
     * Handle fallback execution
     * @param context Execution context with method and failure information
     * @return Fallback result
     */
    T handle(ExecutionContext context);
}

// Method information
interface Method {
    String getName();
    Class<?>[] getParameterTypes();
    Class<?> getReturnType();
    Class<?> getDeclaringClass();
}

Install with Tessl CLI

npx tessl i tessl/maven-io-quarkus--quarkus-smallrye-fault-tolerance

docs

asynchronous-strategies.md

bulkhead-strategies.md

circuit-breaker-strategies.md

configuration.md

fallback-strategies.md

index.md

programmatic-api.md

rate-limiting-strategies.md

retry-strategies.md

timeout-strategies.md

tile.json