LogoLogo
  • README
  • VERSION 9
    • Version Begins
  • Overview
    • Show me the code!
    • Basic Concepts
    • Why Brighter?
  • Brighter Configuration
    • Basic Configuration
    • How Configuring the Command Processor Works
    • How Configuring a Dispatcher for an External Bus Works
    • RabbitMQ Configuration
    • AWS SNS Configuration
    • Kafka Configuration
    • Azure Service Bus Configuration
    • Azure Archive Provider Configuration
  • Darker Configuration
    • Basic Configuration
  • Brighter Request Handlers and Middleware Pipelines
    • Building an Async Pipeline of Request Handlers
    • Basic Configuration
    • How to Implement an Async Request Handler
    • Requests, Commands and an Events
    • Dispatching Requests
    • Dispatching An Async Request
    • Returning results from a Handler
    • Using an External Bus
    • Message Mappers
    • Routing
    • Building a Pipeline of Request Handlers
    • Passing information between Handlers in the Pipeline
    • Failure and Dead Letter Queues
    • Supporting Retry and Circuit Breaker
    • Failure and Fallback
    • Feature Switches
  • Guaranteed At Least Once
    • Outbox Support
    • Inbox Support
    • EFCore Outbox
    • Dapper Outbox
    • Dynamo Outbox
    • MSSQL Inbox
    • MySQL Inbox
    • Postgres Inbox
    • Sqlite Inbox
    • Dynamo Inbox
  • Darker Query Handlers and Middleware Pipelines
    • How to Implement a Query Handler
  • Health Checks and Observability
    • Logging
    • Monitoring
    • Health Checks
    • Telemetry
  • Command, Processors and Dispatchers
    • Command, Processor and Dispatcher Patterns
  • Under the Hood
    • How The Command Processor Works
    • How Service Activator Works
  • Event Driven Architectures
    • Microservices
    • Event Driven Collaboration
    • Event Carried State Transfer
    • Outbox Pattern
  • Task Queues
    • Using a Task Queue
  • FAQ
    • FAQ
  • END OF VERSION
    • Version Ends
  • VERSION 10
    • Version Begins
  • Overview
    • Show me the code!
    • Basic Concepts
    • Why Brighter?
  • Brighter Configuration
    • Basic Configuration
    • How Configuring the Command Processor Works
    • How Configuring a Dispatcher for an External Bus Works
    • RabbitMQ Configuration
    • AWS SNS Configuration
    • Kafka Configuration
    • Azure Service Bus Configuration
    • Azure Archive Provider Configuration
  • Darker Configuration
    • Basic Configuration
  • Brighter Request Handlers and Middleware Pipelines
    • Building an Async Pipeline of Request Handlers
    • Basic Configuration
    • How to Implement an Async Request Handler
    • Requests, Commands and an Events
    • Dispatching Requests
    • Dispatching An Async Request
    • Returning results from a Handler
    • Using an External Bus
    • Message Mappers
    • Routing
    • Building a Pipeline of Request Handlers
    • Passing information between Handlers in the Pipeline
    • Failure and Dead Letter Queues
    • Supporting Retry and Circuit Breaker
    • Failure and Fallback
    • Feature Switches
  • Guaranteed At Least Once
    • Outbox Support
    • Inbox Support
    • EFCore Outbox
    • Dapper Outbox
    • Dynamo Outbox
    • MSSQL Inbox
    • MySQL Inbox
    • Postgres Inbox
    • Sqlite Inbox
    • Dynamo Inbox
  • Darker Query Handlers and Middleware Pipelines
    • How to Implement a Query Handler
  • Health Checks and Observability
    • Logging
    • Monitoring
    • Health Checks
    • Telemetry
  • Command, Processors and Dispatchers
    • Command, Processor and Dispatcher Patterns
  • Under the Hood
    • How The Command Processor Works
    • How Service Activator Works
  • Event Driven Architectures
    • Microservices
    • Event Driven Collaboration
    • Event Carried State Transfer
    • Outbox Pattern
  • Task Queues
    • Using a Task Queue
  • FAQ
    • FAQ
  • END OF VERSION
    • Version Ends
Powered by GitBook
On this page
  • Calling the Fallback Pipeline
  • Using the FallbackPolicy Attribute
  • Scope of a Fallback

Was this helpful?

Edit on GitHub
  1. Brighter Request Handlers and Middleware Pipelines

Failure and Fallback

PreviousSupporting Retry and Circuit BreakerNextFeature Switches

Last updated 1 year ago

Was this helpful?

You may want some sort of backstop exception handler, that allows you to take compensating action, such as undoing any partially committed work, issuing a compensating transaction, or queuing work for later delivery (perhaps using the ).

To support this we provide a IHandleRequests<TRequest>Fallback method. In the Fallback method you write your code to run in the event of failure.

Calling the Fallback Pipeline

We provide a FallbackPolicy Attribute that you can use on your IHandleRequests<TRequest>.Handle() method. The implementation of the Fallback Policy Handler is straightforward: it creates a backstop exception handler by encompassing later requests in the in a try...catch block. You can configure it to catch all exceptions, or just when a Circuit Breaker has tripped.

When the Fallback Policy Handler catches an exception it calls the IHandleRequests<TRequest>.Fallback() method of the next Handler in the pipeline, as determined by IHandleRequests<TRequest>.Successor

The implementation of RequestHandler<T>.Fallback() uses the same approach as it uses for RequestHandler<T>.Handle(). This means that the request to take compensating action for failure, flows through the same pipeline as the request for service, allowing each Handler in the chain to contribute.

In addition the Fallback Policy Handler makes the originating exception available to subsequent Handlers using the Context Bag with the key: CAUSE_OF_FALLBACK_EXCEPTION

Using the FallbackPolicy Attribute

The following example shows a Handler with Request Handler Attributes for that is configured with a Fallback Policy which catches a Broken Circuit Exception (raised when the Circuit Breaker is tripped) and initiates the Fallback chain.

public class MyFallbackProtectedHandler: RequestHandler<MyCommand>
{
    [FallbackPolicy(backstop: false, circuitBreaker: true, step: 1)]
    [UsePolicy(new [] {}"MyCircuitBreakerStrategy", "MyRetryStrategy"}, step: 2)]
    public override MyCommand Handle(MyCommand command)
    {
        /*Do some work that can fail*/
    }

    public override MyCommand Fallback(MyCommand command)
    {
        if (Context.Bag.ContainsKey(FallbackPolicyHandler<MyCommand>.CAUSE_OF_FALLBACK_EXCEPTION))
        {
            /*Use fallback information to determine what action to take*/
        }
        return base.Fallback(command);
    }
}

Scope of a Fallback

Where you put any FallbackPolicy attribute determines what exceptions it will call your Fallback method to guard against. This is controlled by the Step parameter. Remember that you encapsulate anything with a higher Step and can react to an exception thrown there.

External Bus
Request Handling Pipeline
Broken Circuit Exceptions
Russian Doll
Retry and Circuit Breaker policies