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/