Fallback - App-vNext/Polly GitHub Wiki

Fallback Policy (v5.0 onwards)

Note

This documentation describes the previous Polly v7 API. If you are using the new v8 API, please refer to pollydocs.org.

Purpose

To provide a substitute value (or substitute action to be actioned) in the event of failure.

Premise: 'If all else fails, degrade gracefully'

Outright failures will still occur: plan for what you will do when that happens.

Syntax

TResult-returning calls

Return a specific fallback result:

Policy<UserAvatar>
   .Handle<Whatever>()
   .Fallback<UserAvatar>(UserAvatar.Blank)

Run a function to provide a fallback result:

Policy<UserAvatar>
   .Handle<Whatever>()
   .Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar())

With the second example, the fallback is of course not evaluated unless it is actually needed.

void-returning calls

A FallbackPolicy may also be used on void-returning calls. In this case, it specifies an alternate Action to be run if the policy handles a fault (rather than substitute return value).

Policy
   .Handle<Whatever>()
   .Fallback(() => DoFallbackAction())

Syntax examples above are sync; comparable async overloads exist for asynchronous operation. See readme and wiki for more details.

Operation

  • executes the supplied delegate
  • if the delegate throws a handled exception or returns a handled result:
    • calls any configured onFallback/Async delegate
    • then calls the configured fallback Func/Action

Interacting with policy operation

OnFallback

An optional onFallback / onFallbackAsync delegate allows specific code to be executed (for example for logging) before the fallback Func/Action is invoked.

// Specify a substitute value or func, calling an action (eg for logging) if the fallback is invoked.
Policy<UserAvatar>
   .Handle<Whatever>()
   .Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (result, context) =>
    {
        logger.Error($"{context.PolicyKey} at {context.OperationKey}: fallback value substituted, due to: {result.Exception}.");
    });

FallbackPolicy with ExecuteAndCapture()

Note that .ExecuteAndCapture/Async(...) captures whether the overall execution result is one that would have been considered a failure by the policy. Therefore, if your FallbackPolicy replaces a failure result with one that would be considered a success (as many fallback policies do - the "graceful degrade" pattern), then .ExecuteAndCapture/Async(...) will naturally report PolicyResult.Outcome == OutcomeType.Success.

Thread safety and policy reuse

Thread safety

FallbackPolicy is thread-safe: multiple calls may safely be placed concurrently through a policy instance.

Policy reuse

FallbackPolicy instances may be re-used across multiple call sites.

When reusing policies, use an OperationKey to distinguish different call-site usages within logging and metrics.

⚠️ **GitHub.com Fallback** ⚠️