Skip to main content
The fallback strategy provides an alternative value or action when an operation fails.

FallbackStrategyOptions

Configures the fallback resilience strategy.
public class FallbackStrategyOptions<TResult> : ResilienceStrategyOptions

Properties

ShouldHandle
Func<FallbackPredicateArguments<TResult>, ValueTask<bool>>
required
A predicate that determines whether the fallback should be executed for a given outcome.Default: Falls back on any exception except OperationCanceledException.
FallbackAction
Func<FallbackActionArguments<TResult>, ValueTask<Outcome<TResult>>>
required
The fallback action to execute when the ShouldHandle predicate evaluates to true.This property is required and must be set.
OnFallback
Func<OnFallbackArguments<TResult>, ValueTask>?
default:"null"
An event delegate raised when a fallback happens.

Extension Methods

Add fallback strategies to a resilience pipeline:
public static ResiliencePipelineBuilder<TResult> AddFallback<TResult>(
    this ResiliencePipelineBuilder<TResult> builder,
    FallbackStrategyOptions<TResult> options)

Usage Examples

Simple Fallback Value

var fallbackOptions = new FallbackStrategyOptions<string>
{
    ShouldHandle = args => new ValueTask<bool>(args.Outcome.Exception is not null),
    FallbackAction = args =>
    {
        return new ValueTask<Outcome<string>>(
            Outcome.FromResult("Fallback value")
        );
    },
    OnFallback = args =>
    {
        Console.WriteLine("Fallback executed!");
        return ValueTask.CompletedTask;
    }
};

var pipeline = new ResiliencePipelineBuilder<string>()
    .AddFallback(fallbackOptions)
    .Build();

var result = await pipeline.ExecuteAsync(async ct =>
{
    return await FetchDataAsync(ct);
});

Fallback with Alternative Action

var fallbackOptions = new FallbackStrategyOptions<UserData>
{
    ShouldHandle = args => new ValueTask<bool>(
        args.Outcome.Exception is HttpRequestException
    ),
    FallbackAction = async args =>
    {
        // Try an alternative data source
        var cachedData = await GetCachedUserDataAsync(args.Context.CancellationToken);
        return Outcome.FromResult(cachedData);
    }
};

Conditional Fallback Based on Result

var fallbackOptions = new FallbackStrategyOptions<ApiResponse>
{
    ShouldHandle = args => new ValueTask<bool>(
        args.Outcome.Result?.StatusCode == 503 // Service Unavailable
    ),
    FallbackAction = args =>
    {
        var fallbackResponse = new ApiResponse
        {
            StatusCode = 200,
            Data = GetDefaultData()
        };
        return new ValueTask<Outcome<ApiResponse>>(
            Outcome.FromResult(fallbackResponse)
        );
    }
};

FallbackActionArguments

Arguments passed to the FallbackAction delegate.
public readonly struct FallbackActionArguments<TResult>
{
    public ResilienceContext Context { get; }
    public Outcome<TResult> Outcome { get; }
}

Outcome

The Outcome<TResult> type represents either a successful result or an exception:
// Create from result
var outcome = Outcome.FromResult(myValue);

// Create from exception
var outcome = Outcome.FromException<TResult>(myException);

// Check outcome
if (outcome.Exception is not null)
{
    // Handle exception
}
else
{
    var result = outcome.Result;
}

Build docs developers (and LLMs) love