Andrea Cosentino created CAMEL-25024:
----------------------------------------
Summary: camel-mongodb - the consumers discard a failed exchange
and advance past it
Key: CAMEL-25024
URL: https://issues.apache.org/jira/browse/CAMEL-25024
Project: Camel
Issue Type: Bug
Components: camel-mongodb
Reporter: Andrea Cosentino
Assignee: Andrea Cosentino
h3. Summary
Both MongoDB consumers swallow a route failure without a trace and then move
their position past the
message that failed, so the exchange is lost and nothing records it.
h3. Details
{{MongoDbChangeStreamsThread.doRun()}}:
{code:java}
try {
consumer.getProcessor().process(exchange);
this.resumeToken = currentResumeToken;
commitManager.recordResumeToken(currentResumeToken);
commitManager.commit();
} catch (Exception ignored) {
}
{code}
{{MongoDbTailingThread.doRun()}}:
{code:java}
try {
consumer.getProcessor().process(exchange);
} catch (Exception e) {
// do nothing
}
tailTracking.setLastVal(dbObj);
{code}
Neither calls {{getExceptionHandler()}}, so {{bridgeErrorHandler}} has no
effect on these consumers and a
route failure produces no log output whatsoever - the empty catch discards the
exception entirely.
The position advances regardless:
* *Change streams*: the failed event's resume token is not committed, but the
next event that succeeds
commits its own, so the persisted position steps over the failure. The event
is skipped permanently and
silently.
* *Tailable cursor*: {{tailTracking.setLastVal(dbObj)}} sits outside the try,
so it runs even when
processing threw. With {{persistentTailTracking=true}} the record is skipped
across restarts too.
h3. History
The empty catch predates the visible git history: it is already present in the
2019-08-14 commit that
renamed {{camel-mongodb3}} to {{camel-mongodb}}, and no issue has touched it
since. It does not look like
a considered decision, and nothing documents the at-most-once behaviour it
produces.
h3. Proposed fix
Hand the failure to {{getExceptionHandler()}} in both consumers, as other Camel
consumers do, so that it
is logged and {{bridgeErrorHandler}} works. Move {{setLastVal}} inside the
success path of the tailable
consumer so a failed record is not marked as consumed. Whether a failure should
also stop the position
from advancing in the change-streams consumer is a behaviour change worth an
upgrade-guide note.
----
_Reported by Claude Code on behalf of oscerd (Andrea Cosentino)._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)