You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by smashernt <pl...@gmail.com> on 2012/03/21 00:12:12 UTC
doTry/doCatch with an aggregate
Hi Y'all,
I have been working on the error handling for my route and could use a
little help to get me to the finish line.
My strategy is simplistic, I'll put a doTry/doCatch on the main route and
have all the subroutes bubble up the exception. So far, with the aid of the
docs+forum I have been able to do this but there is still one case that I
can't figure out, the aggregate.
Here is a
public class SimpleSplitter {
private String id;
public SimpleSplitter(String id){this.id=id;}
public List<Message> split(Message incoming) {
List<Message>msgs=new java.util.ArrayList<Message>();
for(int i=0;i<5;i++){
DefaultMessage msg=new DefaultMessage();
msg.setHeader("groupid",id);
msg.setHeader("groupsize", 5);
msgs.add(msg);
}
return msgs;
}
}
public class SimpleProcessor implements Processor {
private boolean blowup=false;
public SimpleProcessor(boolean blowup){this.blowup=blowup;}
public void process(Exchange exchange) throws Exception {
System.out.println("PROCESSING "+exchange.getIn().getHeaders());
if(blowup)throw new RuntimeException("KABOOM!");
}
}
public void configure() throws Exception {
SimpleSplitter splitter=new SimpleSplitter("first");
SimpleProcessor processor=new SimpleProcessor(false);
SimpleProcessor processorBlowsUp=new SimpleProcessor(true);
from(STARTPOINT_URI)
.doTry()
.to("direct:split_it")
.doCatch(Throwable.class)
.to("log:logic.export?level=ERROR&showStackTrace=true&showCaughtException=true")
.log("In Catch")
.doFinally()
.log("In Finally")
.end()
.end();
from("direct:split_it")
.errorHandler(noErrorHandler())
.split(bean(splitter)).parallelProcessing()
.to("direct:process_it");
from("direct:process_it")
.errorHandler(noErrorHandler())
.process(processor)
.to("direct:aggregate_it");
from("direct:aggregate_it")
.errorHandler(noErrorHandler())
.aggregate(header("groupid"),new UseLatestAggregationStrategy())
.completionSize(header("groupsize"))
.to("direct:postprocess_it");
from("direct:postprocess_it")
.errorHandler(noErrorHandler())
.process(processorBlowsUp);
}
Ok, hopefully that comes through reasonably formatted. The idea here is that
I have a main route with a try/catch/finally and in the try i call out to
various subroutes, specifically i 1)split it, 2) process it, 3)aggregate it,
and 4) post process it.
I plant runtime exceptions in various places of the subroutes and expect the
doCatch to be called. This works in all cases except for the postprocess_it
subroute. If I can cut out the aggregate and go straight to the postprocess
subroute, then it works, so I know the aggregator is "handling" the
exception, the doCatch does not get called, but the doFinally does.
I need your help in identifying what camel-fu is needed around the aggregate
so that it doesn't try to handle the exception and just let it bubble up to
the parent's doCatch.
thanx in advance!
--
View this message in context: http://camel.465427.n5.nabble.com/doTry-doCatch-with-an-aggregate-tp5581510p5581510.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: doTry/doCatch with an aggregate
Posted by Claus Ibsen <cl...@gmail.com>.
On Wed, Mar 21, 2012 at 1:56 PM, smashernt <pl...@gmail.com> wrote:
> Thanx Claus, knowing that I went ahead and gave the aggregator's children
> their own doTry/doCatch and in the doCatch I direct it to my original
> doCatch subroute.
> ie:
> from(STARTPOINT_URI)
> .doTry()
> .to("direct:split_it")
> .doCatch(Throwable.class)
> .to("direct:catch_all")
> .doFinally()
> .log("In Finally")
> .end()
> .end();
> ...
> from("direct:aggregate_it")
> .errorHandler(noErrorHandler())
>
> .aggregate(header("groupid"),myAggStrategy).completionSize(header("groupSize"))
> .doTry()
> .to("direct:postprocess_it")
> .doCatch()
> .to("direct:catch_all")
> .end()
> .end()
>
> So that the new message that aggregate creates will eventually land in the
> subroute that handles all my errors.
> Side question, is the doTry/doCatch syntax :
> doTry()...doCatch()..end()..end() or is it doTry()..doCatch()..end() ? From
> reading the commit comments it appears like this flipped back and forth a
> few times, I just want to make sure I have it right (for latest release).
>
You only need the end() in the last doCatch or doFinally.
You dont need an end on the doTry as it knows it ends when doCatch comes.
> --
> View this message in context: http://camel.465427.n5.nabble.com/doTry-doCatch-with-an-aggregate-tp5581510p5582798.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
--
Claus Ibsen
-----------------
CamelOne 2012 Conference, May 15-16, 2012: http://camelone.com
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.blogspot.com/
Author of Camel in Action: http://www.manning.com/ibsen/
Re: doTry/doCatch with an aggregate
Posted by smashernt <pl...@gmail.com>.
Thanx Claus, knowing that I went ahead and gave the aggregator's children
their own doTry/doCatch and in the doCatch I direct it to my original
doCatch subroute.
ie:
from(STARTPOINT_URI)
.doTry()
.to("direct:split_it")
.doCatch(Throwable.class)
.to("direct:catch_all")
.doFinally()
.log("In Finally")
.end()
.end();
...
from("direct:aggregate_it")
.errorHandler(noErrorHandler())
.aggregate(header("groupid"),myAggStrategy).completionSize(header("groupSize"))
.doTry()
.to("direct:postprocess_it")
.doCatch()
.to("direct:catch_all")
.end()
.end()
So that the new message that aggregate creates will eventually land in the
subroute that handles all my errors.
Side question, is the doTry/doCatch syntax :
doTry()...doCatch()..end()..end() or is it doTry()..doCatch()..end() ? From
reading the commit comments it appears like this flipped back and forth a
few times, I just want to make sure I have it right (for latest release).
--
View this message in context: http://camel.465427.n5.nabble.com/doTry-doCatch-with-an-aggregate-tp5581510p5582798.html
Sent from the Camel - Users mailing list archive at Nabble.com.
Re: doTry/doCatch with an aggregate
Posted by Claus Ibsen <cl...@gmail.com>.
Hi
The aggregator is a stateful EIP pattern. So the original message will complete.
Then when the aggreagator complete it sends out a new message. And
that new message is not running inside the do .. try.
On Wed, Mar 21, 2012 at 12:12 AM, smashernt <pl...@gmail.com> wrote:
> Hi Y'all,
> I have been working on the error handling for my route and could use a
> little help to get me to the finish line.
> My strategy is simplistic, I'll put a doTry/doCatch on the main route and
> have all the subroutes bubble up the exception. So far, with the aid of the
> docs+forum I have been able to do this but there is still one case that I
> can't figure out, the aggregate.
> Here is a
>
> public class SimpleSplitter {
> private String id;
> public SimpleSplitter(String id){this.id=id;}
> public List<Message> split(Message incoming) {
> List<Message>msgs=new java.util.ArrayList<Message>();
> for(int i=0;i<5;i++){
> DefaultMessage msg=new DefaultMessage();
> msg.setHeader("groupid",id);
> msg.setHeader("groupsize", 5);
> msgs.add(msg);
> }
> return msgs;
> }
> }
> public class SimpleProcessor implements Processor {
> private boolean blowup=false;
> public SimpleProcessor(boolean blowup){this.blowup=blowup;}
> public void process(Exchange exchange) throws Exception {
> System.out.println("PROCESSING "+exchange.getIn().getHeaders());
> if(blowup)throw new RuntimeException("KABOOM!");
> }
> }
> public void configure() throws Exception {
> SimpleSplitter splitter=new SimpleSplitter("first");
> SimpleProcessor processor=new SimpleProcessor(false);
> SimpleProcessor processorBlowsUp=new SimpleProcessor(true);
>
> from(STARTPOINT_URI)
> .doTry()
> .to("direct:split_it")
> .doCatch(Throwable.class)
>
> .to("log:logic.export?level=ERROR&showStackTrace=true&showCaughtException=true")
> .log("In Catch")
> .doFinally()
> .log("In Finally")
> .end()
> .end();
>
> from("direct:split_it")
> .errorHandler(noErrorHandler())
> .split(bean(splitter)).parallelProcessing()
> .to("direct:process_it");
>
> from("direct:process_it")
> .errorHandler(noErrorHandler())
> .process(processor)
> .to("direct:aggregate_it");
>
> from("direct:aggregate_it")
> .errorHandler(noErrorHandler())
> .aggregate(header("groupid"),new UseLatestAggregationStrategy())
> .completionSize(header("groupsize"))
> .to("direct:postprocess_it");
>
> from("direct:postprocess_it")
> .errorHandler(noErrorHandler())
> .process(processorBlowsUp);
> }
> Ok, hopefully that comes through reasonably formatted. The idea here is that
> I have a main route with a try/catch/finally and in the try i call out to
> various subroutes, specifically i 1)split it, 2) process it, 3)aggregate it,
> and 4) post process it.
> I plant runtime exceptions in various places of the subroutes and expect the
> doCatch to be called. This works in all cases except for the postprocess_it
> subroute. If I can cut out the aggregate and go straight to the postprocess
> subroute, then it works, so I know the aggregator is "handling" the
> exception, the doCatch does not get called, but the doFinally does.
> I need your help in identifying what camel-fu is needed around the aggregate
> so that it doesn't try to handle the exception and just let it bubble up to
> the parent's doCatch.
> thanx in advance!
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/doTry-doCatch-with-an-aggregate-tp5581510p5581510.html
> Sent from the Camel - Users mailing list archive at Nabble.com.
--
Claus Ibsen
-----------------
CamelOne 2012 Conference, May 15-16, 2012: http://camelone.com
FuseSource
Email: cibsen@fusesource.com
Web: http://fusesource.com
Twitter: davsclaus, fusenews
Blog: http://davsclaus.blogspot.com/
Author of Camel in Action: http://www.manning.com/ibsen/