Links

Error Handling

To keep the system reliable and resilient it's important to handle errors with grace. Ecotone provides solutions to handle failures within the system in order to self-heal the application or in case of unrecoverable errors store Error Messages for later investigation.

Instant Retries

In case your Message Handler can be retried instantly, you may set up Instant Retries.

Command Bus Instant Retries

In order to set up instant retries for Command Bus, you Service Context configuration.
#[ServiceContext]
public function registerRetries()
{
return InstantRetryConfiguration::createWithDefaults()
->withCommandBusRetry(
true, // is enabled
3, // max retries
[DatabaseConnectionFailure::class, OptimisticLockingException::class] // list of exceptions to be retried, leave empty if all should be retried
)
}
This will retry your synchronous Command Handlers.

Asynchronous Instant Retries

#[ServiceContext]
public function registerRetries()
{
return InstantRetryConfiguration::createWithDefaults()
->withAsynchronousEndpointsRetry(
true, // is enabled
3, // max retries
[DatabaseConnectionFailure::class, OptimisticLockingException::class] // list of exceptions to be retried, leave empty if all should be retried
)
}
This will retry instantly when your message is handled asynchronously. This applies to Command and Events. Take under consideration that Ecotone isolates handling asynchronous events, so it's safe to retry them.
Instant retries may be useful in case of temporary issues, like optimistic locking, momentary unavailability of the external service which we want to call or database connection failure. By using instant retries for asynchronous endpoints we keep message ordering and in case of we can't recover, delayed retries may kick in.

Error Channel

Ecotone comes with solution that allow to push Error Messages to error channel. Depending on what subscribing to error channel you may provide different behaviour. From logging, storing or even discarding the message.

Error Channel

The error channel is channel defined for handling failed messages. As a default it's turned off. We may set up error channel for specific consumer
- Symfony
- Laravel
- Lite
Setting up Error Channel means that Message Consumer will send Error Message to error channel and then continue handling next messages. After sending Error Message to error channel, message is considered handled.

Manually Handling Error Messages from Error Channel

After setting it up default error channel to "errorChannel" we may subscribe to the errors by setting up ServiceActivator:
#[ServiceActivator("errorChannel")]
public function handle(ErrorMessage $errorMessage): void
{
// do something with ErrorMessage
}
Service Activator are endpoints like Command Handlers, however they are not exposed using Command/Event/Query Buses. You may use them for internal handling.

Using Delayed Retry Strategy

If you want to use inbuilt Error Retry Strategy and set retry attempts, backoff strategy, initial delay etc, you may configure using ErrorHandlerConfiguration from ServiceContext.
#[ServiceContext]
public function errorConfiguration()
{
return ErrorHandlerConfiguration::createWithDeadLetterChannel(
"errorChannel",
RetryTemplateBuilder::exponentialBackoff(1000, 10)
->maxRetryAttempts(3),
"dlqErrorChannel"
);
}
------
#[ServiceActivator("dlqErrorChannel")]
public function handle(ErrorMessage $errorMessage): void
{
// do something with ErrorMessage that can't be recovered
}

Dbal Error Channel

Ecotone comes with full support for managing full life cycle of a error message by using Dbal Module.
In order to enable full Error Message life cycle based on Dbal Module point yourdefaultErrorChannel to errorChannel. Read here how to do it for:
After enabling set your errorChannel to dbal_dead_letter (no retries) or use it with ErrorHandlerConfiguration to provide retries and then store it in Dbal DLQ.
#[ServiceContext]
public function errorConfiguration()
{
return ErrorHandlerConfiguration::createWithDeadLetterChannel(
"errorChannel",
RetryTemplateBuilder::exponentialBackoff(1000, 10)
->maxRetryAttempts(3),
"dbal_dead_letter"
);
}

Discarding Error Messages immediately

By default if no Error Channel is defined, message will be requeued, you may throw RejectMessageException if you want to reject and drop it.
The other option is to set your error channel or dead letter channel as nullChannel.
You may set up above configurations to work for given consumer instead of setting them globally.

Ecotone Pulse

Ecotone Pulse is application for managing your Error Messages directly from Web Application. This way you can connect all your services to single place and review, retry and delete Error Messages.
Read more in Ecotone Pulse section.

Materials

Demo implementation