Ecotone
comes with solution called Error Channel.
Error Channel is a place where unrecoverable Errors can go, this way we can preserve Error Messages even if we can't handle anyhow.
Error Channel may log those Messages, store them in database, push them to some Asynchronous Channel. The what is to be done is flexibile and can be adjusted to Application needs.
Error Channel can be configured per Message Consumer, or globally as default Error Channel for all Message Consumers:
- Symfony
- Laravel
- Lite
{% tabs %} {% tab title="Symfony" %} config/packages/ecotone.yaml
ecotone:
defaultErrorChannel: "errorChannel"
{% endtab %}
{% tab title="Laravel" %} config/ecotone.php
return [
'defaultErrorChannel' => 'errorChannel',
];
{% endtab %}
{% tab title="Lite" %}
$ecotone = EcotoneLite::bootstrap(
configuration: ServiceConfiguration::createWithDefaults()
->withDefaultErrorChannel('errorChannel')
);
{% endtab %} {% endtabs %}
class Configuration
{
#[ServiceContext]
public function configuration() : array
{
return [
// For Message Consumer orders, configure error channel
PollingMetadata::create("orders")
->setErrorChannelName("errorChannel")
];
}
}
{% hint style="info" %}
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 as long as Error Handler does not throw exception.
{% endhint %}
To handle incoming Error Messages, we can bind to our defined Error Channel using ServiceActivator:
#[ServiceActivator("errorChannel")]
public function handle(ErrorMessage $errorMessage): void
{
// do something with ErrorMessage
}
{% hint style="info" %}
Service Activator are endpoints like Command Handlers, however they are not exposed using Command/Event/Query Buses.
You may use them for internal handling.
{% endhint %}
We can also use inbuilt retry mechanism, that will be resend Error Message to it's original Message Channel with delay. If our Default Error Channel is configured for name "errorChannel", then we can connect it like bellow:
#[ServiceContext]
public function errorConfiguration()
{
return ErrorHandlerConfiguration::create(
"errorChannel",
RetryTemplateBuilder::exponentialBackoff(1000, 10)
->maxRetryAttempts(3)
);
}
If for some cases we want to discard Error Messages, we can set up error channel to default inbuilt one called "nullChannel".
That may be used in combination of retries, if after given attempt Message is still not handled, then discard:
#[ServiceContext]
public function errorConfiguration()
{
return ErrorHandlerConfiguration::createWithDeadLetterChannel(
"errorChannel",
RetryTemplateBuilder::exponentialBackoff(1000, 10)
->maxRetryAttempts(3),
// if retry strategy will not recover, then discard
"nullChannel"
);
}
Ecotone comes with full support for managing full life cycle of a error message. Read more in next section.