shashank created CAMEL-26430:
--------------------------------

             Summary: camel-core - RedeliveryErrorHandler: a redelivery whose 
processor throws hangs the exchange (RedeliveryTask.redeliver has no try/catch)
                 Key: CAMEL-26430
                 URL: https://issues.apache.org/jira/browse/CAMEL-26430
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: shashank
            Assignee: shashank


Follow-up of CAMEL-26327 (apache/camel#28750), asked for in its review.

{{RedeliveryErrorHandler.RedeliveryTask.run()}} wraps its work in a try/catch: 
an unexpected exception is set on the exchange, the task is released and the 
callback is called, so the exchange completes (failed). 
{{RedeliveryTask.redeliver()}} has no such guard. It runs as a task of its own 
on the reactive executor:

* {{reactiveExecutor.schedule(this::redeliver)}} for an immediate redelivery 
and after a synchronous redelivery delay ({{runSynchronousRedelivery}}),
* {{executorService.schedule(() -> reactiveExecutor.schedule(this::redeliver), 
redeliveryDelay, ...)}} for an asynchronous delayed redelivery.

If anything in {{redeliver()}} throws, for example an {{AsyncProcessor}} (or a 
step hook) whose {{process(exchange, callback)}} throws instead of setting the 
exception on the exchange, or a failure in {{prepareExchangeForRedelivery}} / 
{{deliverToOnRedeliveryProcessor}}, the exception reaches 
{{DefaultReactiveExecutor}}, which logs it ({noformat}Error executing reactive 
work due to ... This exception is ignored.{noformat}) and drops it. The 
callback of the exchange is never called, so the caller waits forever (a 
synchronous {{template.send}} or a consumer thread blocks; an async caller 
never completes). The first delivery does not hang in the same case, because 
{{run()}} catches it.

This is the general reason why a processor that throws on redelivery hangs 
instead of failing: CAMEL-26327 (a routing slip whose step had lost its 
producer threw an NPE on redelivery) and CAMEL-26301 (the tokenizer) had the 
same symptom.

*Proposal*
* Give {{redeliver()}} the same guard as {{run()}}: catch the exception, set it 
on the exchange, release the task and call the callback (or loop back through 
{{reactiveExecutor.schedule(this)}} so the error handler sees the new failure, 
as when the onRedelivery processor fails). Which of the two is a decision for 
the fix: looping back lets the error handler handle or redeliver the new 
failure, the direct callback matches {{run()}}.
* A test with an {{AsyncProcessor}} that throws from {{process(exchange, 
callback)}} on the second call, with immediate, synchronous delayed and 
asynchronous delayed redelivery: the send must complete (failed or handled) 
instead of hanging.

_Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to