Reputation: 32969
I have an ErrorHandler
(DefaultErrorHandler
) into which I have provided an onRedelivery
ref. By default the ErrorHandler
retries unlimited times. However, if a certain condition exists (currently determined by the onRedelivery
ref) I would like to exit the redelivery loop and execute a different route.
My initial thought was to have the onRedelivery
ref throw and exception and have an appropriate onException
direct this to the appropriate route. However, I find that the RedeliveryErrorHandler
catches this exception and keeps looping.
I have also found that I can set the Exchange.REDELIVERY_EXHAUSTED
to true which will exit the redelivery loop but will not direct me to my recovery route.
Any suggestions?
Edit
So I have found that if I add the original exception type to the onException
of the exception type in the RouteBuilder
in which I have my ErrorHandler
, and if I set the Exchange.REDELIVERY_EXHAUSTED
to true, the original exception will be thrown to the RouteBuilder
scope and caught by the onException
. However, I would really prefer to throw and catch a new exception type so that the handling is explicit to this case.
Answer
So Peter's
suggestion of using retryWhile
was great in that it allows me to programmatically determine when to stop retrying. It's too. It only went half way thought. The second part was to send the failing exchange to a new / different route for error handling. This is accomplished by using the DeadLetterChannel
instead of the DefaultErrorHandler
.
Upvotes: 0
Views: 272
Reputation: 7646
Use retryWhile
in combination with deadLetterChannel
:
public class MyRouteBuilder extends RouteBuilder {
@Override
public void configure() {
errorHandler(deadLetterChannel("direct:special")
.retryWhile(method(new MyPredicate())));
from("direct:start")
.log("Starting...")
.throwException(new Exception("dummy"));
from("direct:special")
.log("...Special");
}
}
public class MyPredicate implements Predicate {
@Override
public boolean matches(final Exchange exchange) {
AtomicInteger counter = exchange.getProperty("myCounter");
if (counter == null) {
counter = new AtomicInteger(0);
exchange.setProperty("myCounter", counter);
}
int count = counter.incrementAndGet();
LOG.info("Count = {}", count);
return count < 3; // or whatever condition is suitable
}
}
This prints:
INFO Starting...
INFO Count = 1
INFO Count = 2
INFO Count = 3
INFO ...Special
Upvotes: 1