Claus Ibsen created CAMEL-25115:
-----------------------------------

             Summary: camel-core - Error handler failure paths: fix bugs found 
in a deep review
                 Key: CAMEL-25115
                 URL: https://issues.apache.org/jira/browse/CAMEL-25115
             Project: Camel
          Issue Type: Bug
          Components: camel-core
            Reporter: Claus Ibsen


A deep look at the failure paths of the error handler (RedeliveryErrorHandler, 
FatalFallbackErrorHandler, DefaultExceptionPolicyStrategy, 
OnCompletionProcessor and DefaultErrorRegistry) found the following bugs:

# An onException *onWhen* predicate that throws an exception escaped from the 
error handler. It is now logged at WARN and regarded as not matching, so 
another onException (or the error handler) handles the exchange.
# A *handled*, *continued* or *retryWhile* predicate that throws an exception 
replaced the original exception, and the onException outputs / dead letter 
channel were skipped. It is now logged at WARN and regarded as false; the 
original exception is kept (the predicate exception is attached as suppressed), 
and the exchange is still delivered to the failure processor / dead letter 
channel.
# FatalFallbackErrorHandler kept its "running under" route ids in a mutable 
deque stored as an exchange property, which copies of the exchange 
(splitter/multicast with parallel processing) share. This could detect a 
circular error handler that is not circular (a sibling copy running the same 
route), and the property was never removed. Entries are now tied to the 
exchange instance, and the property is removed when empty.
# An exception from *onPrepareFailure* was set on the exchange, which was then 
still sent to the dead letter queue / failure processor. The exchange is now 
not delivered, and the new exception is handled according to 
deadLetterHandleNewException (the original exception is attached as 
suppressed). This also covers the processor being wrapped and setting the 
exception on the exchange instead of throwing.
# DefaultErrorRegistry recorded every failure-handled event as handled, also 
when the onException did not handle the exception. The handled flag now comes 
from the exchange (a doCatch, which does not set the error handler flag, is 
still handled).
# An exception from *onRedelivery* was set on the exchange which was then 
redelivered with the exception on it (a single output processor would process 
it anyway). It is now treated as a new failure.
# After continued(true), a later unrelated exception on the same exchange got 
the continued exception attached as suppressed (a "previous" exception).
# OnCompletionProcessor did not reset failureHandled before running the 
onCompletion, so an onException could not handle a failure inside an 
onFailureOnly completion, and a handled failure inside the onCompletion leaked 
EXCEPTION_CAUGHT and the error handler handled flag onto the (successful) 
exchange.
# RedeliveryTask.run() did not release the pooled task when an unexpected 
exception was caught.

The fixes are applied to both the non-redelivery (SimpleTask) and redelivery 
(RedeliveryTask) paths.

*Not changed*
* Recursion detection design: a route runs twice before the circuit is 
detected, and a dead letter queue route inheriting the dead letter channel.
* The NoErrorHandler bridge case.
* The isSame heuristic in the error handler.
* The ERRORHANDLER_CIRCUIT_DETECTED property is set but not used by Camel.
* The SimpleTask redelivery policy branch that is never used (tracked in 
CAMEL-24980).

_Claude Code on behalf of Claus Ibsen_



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to