Federico Mariani created CAMEL-25419:
----------------------------------------
Summary: Saga EIP: keep the original exception when compensation
fails, and stop the in-memory saga service from reporting failed compensations
as compensated
Key: CAMEL-25419
URL: https://issues.apache.org/jira/browse/CAMEL-25419
Project: Camel
Issue Type: Bug
Components: camel-core
Affects Versions: 4.22.1
Reporter: Federico Mariani
Assignee: Federico Mariani
Fix For: 4.23.0
Small fixes to how the Saga EIP reports a compensation that could not be done.
h3. 1. The exception that caused the compensation is lost (all saga services)
When a step fails in AUTO completion mode and the compensation then fails as
well, {{SagaProcessor.ifNotException}} replaces the exchange exception with
{{Unable to compensate all required steps of the saga <id>}}, wrapped in a
{{CompletionException}}. The original exception is not kept as the cause or as
a suppressed exception, so the caller cannot see why the saga failed.
With the in-memory service this happens when the compensation endpoint fails
after all retries. With LRA it happens when the call that asks the LRA
coordinator to compensate fails, for example because the coordinator is
unreachable.
*Fix:* keep the original exception on the exchange and add the compensation
failure to it as a suppressed exception.
h3. 2. InMemorySagaService reports a failed compensation as COMPENSATED
After {{maxRetryAttempts}}, {{InMemorySagaCoordinator.doCompensate}} logs a
WARN, then sets the status to {{COMPENSATED}} and removes the saga. A later
{{compensate()}} call on that coordinator completes successfully. The same
applies to completion ({{COMPLETED}}).
*Fix:* set a {{FAILED}} status instead, so a later {{compensate()}} or
{{complete()}} call fails. Also adjust the sentence in saga-eip.adoc that says
the implementation triggers "a manual intervention process": the in-memory
service only logs a warning.
h3. 3. InMemorySagaService drops pending compensation retries on stop, without
a log
If the CamelContext stops while a compensation retry is scheduled, the retry
never runs and nothing is logged. Losing in-flight sagas on stop is expected
for an in-memory service (the docs already say it is not recommended for
production), but it should not be silent.
*Fix:* in {{InMemorySagaService.doStop}}, log a WARN with the ids of the sagas
that are still running, compensating or completing.
h3. Reproducer
A test reproducing all three ({{SagaCompensationFailureTest}} in camel-core)
fails on main (d16cd8827dc3) and will be part of the PR:
* the original exception ("business failure") is not in the exception chain;
* {{compensate()}} on a saga whose compensation failed completes without error;
* a pending compensation retry is dropped on stop and nothing is logged.
_Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v8.20.10#820010)