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
  • Handling Failure
  • Communicating the Outcome of a Command
  • Raising an Event
  • Update a field on the Command

Was this helpful?

Edit on GitHub
  1. Brighter Request Handlers and Middleware Pipelines

Returning results from a Handler

PreviousDispatching An Async RequestNextUsing an External Bus

Last updated 1 year ago

Was this helpful?

We use so a Command does not have return value and CommandDispatcher.Send() does not return anything. Our project Darker provides a Query Processor that can be used to return results in response to queries. You can use both together to provide CQRS.

This in turn leads to a set of questions that we need to answer about common scenarios:

  • How do I handle failure? With no return value, what do I do if my handler fails?

  • How do I communicate the outcome of a command?

Handling Failure

If we don't allow return values, what do you do on failure?

  • The basic failure strategy is to throw an exception. This will terminate the request handling pipeline.

  • If you want Internal Bus support for you can use our support for Policies

  • If you want to Requeue (with Delay) to an External Bus, you should throw a DeferMessageAction exception.

  • Finally you can use our support for a handler to provide backstop exception handling.

  • You can also build your own exception handling into your .

We discuss these options in more detail in .

Communicating the Outcome of a Command

Sometimes you need to provide information to the caller about the outcome of a Command, instead of listening for an Event an.

How do you communicate the outcome of handling a Command? There are two options, which depend on circumstance:

  • Raise an Event

  • Update a field on the Command

Raising an Event

This approach let's you take action in response to a Command by raising an Event within your handler using CommandProcessor.Publish or via an External Bus using CommandProcessor.Post/CommandProcessor.DepositPost.

If you use an Internal Bus these handlers will run immediately, in their own pipeline, before your handler exits. If you use an External Bus you offload the work to another process.

Update a field on the Command

If you are using an Internal Bus and need a return value from a Command you will note that CommandProcessor.Send has a void return value, so you cannot return a value from the handler.

What happens if the caller needs to know the outcome, and can't be signalled via an Event?

In that case add a property to the Command that you can initialize from the Handler. As an example, what happens if you need to return the identity of a newly created entity, so that you can use Darker to retrieve its details? In this case you can create a NewEntityIdentity property in your command that you write a newly created entity's identity to in the Handler, and then inspect the property in your Command in the calling code after the call to commandProcessor.Send(command) completes.

You can think of these as out parameters.

var createTaskCommand = new CreateTaskCommand();
commandProcessor.Send(createTaskCommand);
var newTaskId = createTaskCommand.TaskId;
Command-Query separation
Retry, and Circuit Breaker
Polly
Fallback
Pipeline
Handler Failure