allthingssecurity opened a new pull request, #29295:
URL: https://github.com/apache/camel/pull/29295

   # Description
   
   [CAMEL-26601](https://issues.apache.org/jira/browse/CAMEL-26601)
   
   Follow-up of CAMEL-26464 (#29127): the one case it does not cover, a 
recipient of a recipient list inside a `doTry`.
   
   In a `doTry`, `MulticastProcessor.wrapInErrorHandler` does not put an error 
handler around a recipient; the recipient only gets the unit of work processor 
(a `CamelInternalProcessor`). For a multicast that output is a channel, which 
catches a throw since CAMEL-26464. For a recipient list it is the producer of 
the recipient endpoint. When that producer throws from `process(exchange, 
callback)` instead of setting the exception on the exchange, the exception 
reaches the sub task, the reactive executor logs and drops it, and the 
recipient list never completes. The `doCatch` never runs, and the caller waits 
for good. This holds with the default options and with `synchronous`, 
`parallelProcessing`, `stopOnException` and `shareUnitOfWork`. With a 
`timeout`, the recipient list returns after the timeout without the failure, so 
the `doCatch` does not run there either.
   
   Camel's own seda producer does this: with a bounded queue that is full, and 
neither `blockWhenFull` nor `discardWhenFull` set (the default), it throws 
`IllegalStateException: Queue full` from `process(exchange, callback)`.
   
   ```java
   from("direct:start")
       .doTry()
           .recipientList(constant("seda:work?size=1"))
           .end()
           .to("mock:result")
       .endDoTry()
       .doCatch(IllegalStateException.class)
           .to("mock:caught")
       .end();
   // with the queue full, template.sendBody("direct:start", "x") never returns
   ```
   
   ## The fix
   
   When the multicast does not wrap the output in an error handler, it sets 
`catchProcessorThrows` on the unit of work processor it creates for the output 
(new public setter `CamelInternalProcessor.setCatchProcessorThrows`). That is 
the flag CAMEL-26464 added and `DefaultChannel` sets for steps without an error 
handler, so the same rule applies. A throw before the callback fails the copy 
through the reactive executor and runs the done work of its unit of work. The 
multicast then continues exactly once. A throw after the callback was called is 
rethrown, as before. A plain catch in the sub task would also end the hang, but 
it skips the copy's unit of work, and it continues the exchange twice when the 
producer handed its callback to the reactive executor before it threw.
   
   The CAMEL-26464 entry of the 4.24 upgrade guide now lists these recipients 
too (a second call of the callback is ignored and logged at WARN, as for the 
other steps).
   
   camel-seda should set the exception instead of throwing when the queue is 
full; I will file a separate JIRA for that. This change is still needed for 
other producers that throw.
   
   Main only: it builds on CAMEL-26464, which is not on 4.18.x.
   
   ## Tests
   
   `RecipientListProducerThrowsInDoTryTest`, 9 tests. A producer that throws 
(default, `synchronous`, `parallelProcessing`, `parallelProcessing` with a 
`timeout`, `stopOnException`, `shareUnitOfWork`), one that calls back and then 
throws, and one that hands its callback to the reactive executor and then 
throws: each route must end the same way as the route whose producer sets the 
exception, with as many exchanges done, and the producer must be called once. 
Plus seda with a full queue, which must reach the `doCatch`. On main 7 of the 9 
fail (6 time out; with the timeout, the exchange succeeds without the failure); 
with the fix all 9 pass (20 runs, 180/180).
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to