Reputation: 69
onException(NullPointerException.class)
.handled(true)
.to("google-pubsub:some_topic");
In here, my design is such that for any unforseen error,I want to put the problem message to gcp pubsub error topic.
But I am saying "handled" as true.Hence for any error in publishing to pubsub error topic (say network error etc),the error will be silently ignored !! This is no good for me.Now I lost the message because since it was handled,the message has been acknowledged automatically and the message will not be redelivered by gcp pubsub !!
Please let me know my alternatives
I was just going through the Camel in Action Book.Below is the text
"Camel doesn’t allow further error handling while already handling an error(onException handled is true) . In other words, when Camel detects that another exception was thrown during error handling, it prevents any further action from taking place. This is done by the org.apache.camel.processor.FataFallbackErrorHandler, which catches the new exception, logs a warning, sets this as the exception on the Exchange, and stops any further routing."
This mean if an exception is thrown while handling an exception,the exception will not be propagated,but a warning will be logged and sets an exception on the exchange.
Since an error has been marked in the exchange ,the pub sub message in the exchange will not be marked as Acked,and will be redelivered by pubsub.
Let me test it my self.
Upvotes: 3
Views: 2403
Reputation: 342
Move the exception handling logic to new route and use queue/direct component to handle it. In case of failure you can write your failed message to an error/dlq and come up with a strategy to reprocess them.
Main Route:
onException(Exception.class)
.handled(true)
.to("queue:myapp.exception.handler");
from(direct:mainRoute")
.process("processTransaction")
.to("sql:***");
Exception Handler Route:
onException(Exception.class)
.handled(true)
.maximumRedeliveries(2)
.redeliveryDelay(30000)
.to("queue:myapp.exception.handler.failed") ;
from("queue:myapp.exception.handler")
.to("google-pubsub:some_topic");
Upvotes: 0
Reputation: 8213
Request-reply
patternIf the caller knew operation has failed, they can retry so you will not mark the exception
as handled
One-way
pattern and can afford to lose messageJust like java catch block that catches but doesn't re-throw. May be you log a message. Since you can afford to lose the message, it is fine.
One-way
pattern, you prefer moving the message somewhere on best of effortsExactly like your example. You prefer moving somewhere but if the error hapens on the onException
route, you are ok to lose the message
One-way
pattern and you cannot afford to lose messageIn case of recoverable error, you want to retry a few times but after that you want to move it somewhere else. In the case of irrecoverable error, you want to move it somewhere else straight away. In both cases, if you don't move it, you will endup with infinite loop and your route will be busy repeatedly consuming the same message while others are ignored.
Since you cannot afford to lose the message if the error happens on the onException
route, you cannot mark it as handled
and at the same time, you cannot let it go back and start a infinite loop
So your option here is Dead Letter Channel error handler
When the DeadLetterChannel moves a message to the dead letter endpoint, any new Exception thrown is by default handled by the dead letter channel as well. This ensures that the DeadLetterChannel will always succeed.
Reference
https://camel.apache.org/components/latest/eips/dead-letter-channel.html
Note:
As you can see in the image, DeadLetterChannel is another error handler
Upvotes: 1