You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Ravi Narayana <ra...@gmail.com> on 2007/09/06 09:36:23 UTC

Dead Letter Channel delivers message when it shouldn't?

I have a simple route with a producer in the middle which throws an exception
(java.lang.IllegalArgumentException) as follows:

from("direct:start").process(exceptionThrower).to("mock:result");

As expected, the default error handler (Dead Letter Channel) is triggered
which attempts to redeliver the message a few times. Since all the
redelivery attempt fails, I do not expect the message to end up in my
mock:result endpoint. But I see that the message is finally being delivered
to the mock:result endpoint.

If I add my own exception handler as follows:

exception(IllegalArgumentException.class).to("mock:exception");

then I see the message is delivered to both my mock:exception and mock:resut
endpoints

Am I missing something fundamental here?

Here is the Test case:
================

import junit.framework.TestCase;

import org.apache.camel.CamelContext;
import org.apache.camel.CamelTemplate;
import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.util.jndi.JndiContext;

public class ExceptionTest extends TestCase  {
	private CamelContext camelContext;
	private CamelTemplate<Exchange> template;

	public ExceptionTest(String name) {
		super(name);
	}

	protected void setUp() throws Exception {
		super.setUp();
		JndiContext context = new JndiContext();
		camelContext = new DefaultCamelContext(context);
		template = new CamelTemplate<Exchange>(camelContext);
		camelContext.start();
	}

	public void testException() throws Exception {
		final Processor  exceptionThrower = new Processor() {
			public void process(Exchange exchange) throws Exception  {
				exchange.getIn().setBody("<exception/>");
				throw new IllegalArgumentException("Exception thrown intentionally.");
			}
		};
		RouteBuilder builder = new RouteBuilder() {
			public void configure() {
//				exception(IllegalArgumentException.class).to("mock:exception");
				from("direct:start").process(exceptionThrower).to("mock:result");
			}
		};
		camelContext.addRoutes(builder);

		template.sendBody("direct:start", "<body/>");

		MockEndpoint resultEndpoint = camelContext.getEndpoint("mock:result",
MockEndpoint.class);
		MockEndpoint exceptionEndpoint =
camelContext.getEndpoint("mock:exception", MockEndpoint.class);

		resultEndpoint.expectedMessageCount(0);		
//		exceptionEndpoint.expectedMessageCount(1);
		MockEndpoint.assertIsSatisfied(resultEndpoint, exceptionEndpoint);
	}

	protected void tearDown() throws Exception {
		super.tearDown();
		camelContext.stop();
	}
}

-- 
View this message in context: http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12517101
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Dead Letter Channel delivers message when it shouldn't?

Posted by ajayappa <an...@gmail.com>.

I am using 1.1.0 version.

I updated to latest snapshot from the download page and the issue seemed to
be fixed. But then I noticed that both the files now go to failure folder
(each has 3 copies !!), even though one of them is not throwing any
exception. And success folder is not getting created as expected.

So, I reverted back to 1.1.0 version. And again noticed that both files now
go to success folder even though one of them throws exception. The failed
file correctly goes to failure folder (2 copies indicating failure at two
channels). I can live with this behavior.

But in the below code, no matter how many times I tried, global
errorHandler() DOES NOT work.





James.Strachan wrote:
> 
> Can you confirm which version of Camel you are using?
> 
> On 01/10/2007, ajayappa <an...@gmail.com> wrote:
>>
>> I've same problem. In the below case, if I've two files and one causes
>> failure, both end up in success folder and the one which caused failure
>> goes
>> to failure folder.
>>
>> One more issue, global errorHandler() commented below DOES NOT WORK.
>>
>> Am I doing something wrong ??
>>
>>         public static void main(String[] args) throws Exception {
>>                 CamelContext ctx = new DefaultCamelContext();
>>
>>                 ctx.addRoutes(new RouteBuilder() {
>>                         public void configure() throws Exception {
>> //
>> errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>>                                
>> from("file:src/data?noop=true&recursive=false")
>>
>> .errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>>                                 .convertBodyTo(PersonDocument.class)
>>
>> .errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>>                                 .process(new Processor() {
>>                                                 public void
>> process(Exchange arg0) throws Exception {
>>                                                        
>> System.err.println(arg0);
>>                                                         PersonDocument m
>> = (PersonDocument) arg0.getIn().getBody();
>>                                                        
>> System.err.println(m.getAbstract());
>> //                                                      if(1==1) throw
>> new IllegalArgumentException();
>>                                                 }
>>                                        
>> }).to("file:src/data/../success");
>>                         }
>>                 });
>>
>>
>>
>>
>>
>> James.Strachan wrote:
>> >
>> > On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
>> >>
>> >> After refreshing my workspace with the latest from trunk, it works
>> fine
>> >> now.
>> >> Sorry, I should have done this earlier.
>> >
>> > No worries! :)
>> >
>> > --
>> > James
>> > -------
>> > http://macstrac.blogspot.com/
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12973340
>>
>> Sent from the Camel - Users mailing list archive at Nabble.com.
>>
>>
> 
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> Open Source SOA
> http://open.iona.com
> 
> 

-- 
View this message in context: http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12974084
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Dead Letter Channel delivers message when it shouldn't?

Posted by James Strachan <ja...@gmail.com>.
Can you confirm which version of Camel you are using?

On 01/10/2007, ajayappa <an...@gmail.com> wrote:
>
> I've same problem. In the below case, if I've two files and one causes
> failure, both end up in success folder and the one which caused failure goes
> to failure folder.
>
> One more issue, global errorHandler() commented below DOES NOT WORK.
>
> Am I doing something wrong ??
>
>         public static void main(String[] args) throws Exception {
>                 CamelContext ctx = new DefaultCamelContext();
>
>                 ctx.addRoutes(new RouteBuilder() {
>                         public void configure() throws Exception {
> //
> errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>                                 from("file:src/data?noop=true&recursive=false")
>
> .errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>                                 .convertBodyTo(PersonDocument.class)
>
> .errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
>                                 .process(new Processor() {
>                                                 public void process(Exchange arg0) throws Exception {
>                                                         System.err.println(arg0);
>                                                         PersonDocument m = (PersonDocument) arg0.getIn().getBody();
>                                                         System.err.println(m.getAbstract());
> //                                                      if(1==1) throw new IllegalArgumentException();
>                                                 }
>                                         }).to("file:src/data/../success");
>                         }
>                 });
>
>
>
>
>
> James.Strachan wrote:
> >
> > On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
> >>
> >> After refreshing my workspace with the latest from trunk, it works fine
> >> now.
> >> Sorry, I should have done this earlier.
> >
> > No worries! :)
> >
> > --
> > James
> > -------
> > http://macstrac.blogspot.com/
> >
> >
>
> --
> View this message in context: http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12973340
>
> Sent from the Camel - Users mailing list archive at Nabble.com.
>
>


-- 
James
-------
http://macstrac.blogspot.com/

Open Source SOA
http://open.iona.com

Re: Dead Letter Channel delivers message when it shouldn't?

Posted by ajayappa <an...@gmail.com>.
I've same problem. In the below case, if I've two files and one causes
failure, both end up in success folder and the one which caused failure goes
to failure folder.

One more issue, global errorHandler() commented below DOES NOT WORK.

Am I doing something wrong ??

	public static void main(String[] args) throws Exception {
		CamelContext ctx = new DefaultCamelContext();

		ctx.addRoutes(new RouteBuilder() {
			public void configure() throws Exception {
//			
errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
				from("file:src/data?noop=true&recursive=false")
			
.errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
				.convertBodyTo(PersonDocument.class)
			
.errorHandler(deadLetterChannel("file:src/data/../failure/").maximumRedeliveries(0))
				.process(new Processor() {
						public void process(Exchange arg0) throws Exception {
							System.err.println(arg0);
							PersonDocument m = (PersonDocument) arg0.getIn().getBody();
							System.err.println(m.getAbstract());
//							if(1==1) throw new IllegalArgumentException();
						}
					}).to("file:src/data/../success");
			}
		});
		



James.Strachan wrote:
> 
> On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
>>
>> After refreshing my workspace with the latest from trunk, it works fine
>> now.
>> Sorry, I should have done this earlier.
> 
> No worries! :)
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12973340
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Dead Letter Channel delivers message when it shouldn't?

Posted by James Strachan <ja...@gmail.com>.
On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
>
> After refreshing my workspace with the latest from trunk, it works fine now.
> Sorry, I should have done this earlier.

No worries! :)

-- 
James
-------
http://macstrac.blogspot.com/

Re: Dead Letter Channel delivers message when it shouldn't?

Posted by Ravi Narayana <ra...@gmail.com>.
After refreshing my workspace with the latest from trunk, it works fine now.
Sorry, I should have done this earlier.
Thanks
Ravi

James.Strachan wrote:
> 
> On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
>>
>> I have a simple route with a producer in the middle which throws an
>> exception
>> (java.lang.IllegalArgumentException) as follows:
>>
>> from("direct:start").process(exceptionThrower).to("mock:result");
>>
>> As expected, the default error handler (Dead Letter Channel) is triggered
>> which attempts to redeliver the message a few times. Since all the
>> redelivery attempt fails, I do not expect the message to end up in my
>> mock:result endpoint. But I see that the message is finally being
>> delivered
>> to the mock:result endpoint.
>>
>> If I add my own exception handler as follows:
>>
>> exception(IllegalArgumentException.class).to("mock:exception");
>>
>> then I see the message is delivered to both my mock:exception and
>> mock:resut
>> endpoints
>>
>> Am I missing something fundamental here?
>>
>> Here is the Test case:
>> ================
>>
>> import junit.framework.TestCase;
>>
>> import org.apache.camel.CamelContext;
>> import org.apache.camel.CamelTemplate;
>> import org.apache.camel.Exchange;
>> import org.apache.camel.Processor;
>> import org.apache.camel.builder.RouteBuilder;
>> import org.apache.camel.component.mock.MockEndpoint;
>> import org.apache.camel.impl.DefaultCamelContext;
>> import org.apache.camel.util.jndi.JndiContext;
>>
>> public class ExceptionTest extends TestCase  {
>>         private CamelContext camelContext;
>>         private CamelTemplate<Exchange> template;
>>
>>         public ExceptionTest(String name) {
>>                 super(name);
>>         }
>>
>>         protected void setUp() throws Exception {
>>                 super.setUp();
>>                 JndiContext context = new JndiContext();
>>                 camelContext = new DefaultCamelContext(context);
>>                 template = new CamelTemplate<Exchange>(camelContext);
>>                 camelContext.start();
>>         }
>>
>>         public void testException() throws Exception {
>>                 final Processor  exceptionThrower = new Processor() {
>>                         public void process(Exchange exchange) throws
>> Exception  {
>>                                 exchange.getIn().setBody("<exception/>");
>>                                 throw new
>> IllegalArgumentException("Exception thrown intentionally.");
>>                         }
>>                 };
>>                 RouteBuilder builder = new RouteBuilder() {
>>                         public void configure() {
>> //                             
>> exception(IllegalArgumentException.class).to("mock:exception");
>>                                
>> from("direct:start").process(exceptionThrower).to("mock:result");
>>                         }
>>                 };
>>                 camelContext.addRoutes(builder);
>>
>>                 template.sendBody("direct:start", "<body/>");
>>
>>                 MockEndpoint resultEndpoint =
>> camelContext.getEndpoint("mock:result",
>> MockEndpoint.class);
>>                 MockEndpoint exceptionEndpoint =
>> camelContext.getEndpoint("mock:exception", MockEndpoint.class);
>>
>>                 resultEndpoint.expectedMessageCount(0);
>> //              exceptionEndpoint.expectedMessageCount(1);
>>                 MockEndpoint.assertIsSatisfied(resultEndpoint,
>> exceptionEndpoint);
>>         }
>>
>>         protected void tearDown() throws Exception {
>>                 super.tearDown();
>>                 camelContext.stop();
>>         }
>> }
> 
> Thanks for this great test case! I've added it to subversion...
> http://svn.apache.org/repos/asf/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionTest.java
> 
> I made some minor refactorings to reuse ContextTestSupport to make the
> test case a little simpler & easier to read.
> 
> However the test case works fine for me when using the exception
> handler and when not.
> 
> i.e. the message never carries on to the final "mock:result" and the
> exception handler makes it go to "mock:exception". When not using the
> exception handler I see the dead letter queue deliver to the default
> URI (namely to log an ERROR in log4j)
> 
> Am using trunk though - I wonder how to reproduce this issue? Were you
> using 1.1.0?
> 
> -- 
> James
> -------
> http://macstrac.blogspot.com/
> 
> 

-- 
View this message in context: http://www.nabble.com/Dead-Letter-Channel-delivers-message-when-it-shouldn%27t--tf4390150s22882.html#a12527861
Sent from the Camel - Users mailing list archive at Nabble.com.


Re: Dead Letter Channel delivers message when it shouldn't?

Posted by James Strachan <ja...@gmail.com>.
On 9/6/07, Ravi Narayana <ra...@gmail.com> wrote:
>
> I have a simple route with a producer in the middle which throws an exception
> (java.lang.IllegalArgumentException) as follows:
>
> from("direct:start").process(exceptionThrower).to("mock:result");
>
> As expected, the default error handler (Dead Letter Channel) is triggered
> which attempts to redeliver the message a few times. Since all the
> redelivery attempt fails, I do not expect the message to end up in my
> mock:result endpoint. But I see that the message is finally being delivered
> to the mock:result endpoint.
>
> If I add my own exception handler as follows:
>
> exception(IllegalArgumentException.class).to("mock:exception");
>
> then I see the message is delivered to both my mock:exception and mock:resut
> endpoints
>
> Am I missing something fundamental here?
>
> Here is the Test case:
> ================
>
> import junit.framework.TestCase;
>
> import org.apache.camel.CamelContext;
> import org.apache.camel.CamelTemplate;
> import org.apache.camel.Exchange;
> import org.apache.camel.Processor;
> import org.apache.camel.builder.RouteBuilder;
> import org.apache.camel.component.mock.MockEndpoint;
> import org.apache.camel.impl.DefaultCamelContext;
> import org.apache.camel.util.jndi.JndiContext;
>
> public class ExceptionTest extends TestCase  {
>         private CamelContext camelContext;
>         private CamelTemplate<Exchange> template;
>
>         public ExceptionTest(String name) {
>                 super(name);
>         }
>
>         protected void setUp() throws Exception {
>                 super.setUp();
>                 JndiContext context = new JndiContext();
>                 camelContext = new DefaultCamelContext(context);
>                 template = new CamelTemplate<Exchange>(camelContext);
>                 camelContext.start();
>         }
>
>         public void testException() throws Exception {
>                 final Processor  exceptionThrower = new Processor() {
>                         public void process(Exchange exchange) throws Exception  {
>                                 exchange.getIn().setBody("<exception/>");
>                                 throw new IllegalArgumentException("Exception thrown intentionally.");
>                         }
>                 };
>                 RouteBuilder builder = new RouteBuilder() {
>                         public void configure() {
> //                              exception(IllegalArgumentException.class).to("mock:exception");
>                                 from("direct:start").process(exceptionThrower).to("mock:result");
>                         }
>                 };
>                 camelContext.addRoutes(builder);
>
>                 template.sendBody("direct:start", "<body/>");
>
>                 MockEndpoint resultEndpoint = camelContext.getEndpoint("mock:result",
> MockEndpoint.class);
>                 MockEndpoint exceptionEndpoint =
> camelContext.getEndpoint("mock:exception", MockEndpoint.class);
>
>                 resultEndpoint.expectedMessageCount(0);
> //              exceptionEndpoint.expectedMessageCount(1);
>                 MockEndpoint.assertIsSatisfied(resultEndpoint, exceptionEndpoint);
>         }
>
>         protected void tearDown() throws Exception {
>                 super.tearDown();
>                 camelContext.stop();
>         }
> }

Thanks for this great test case! I've added it to subversion...
http://svn.apache.org/repos/asf/activemq/camel/trunk/camel-core/src/test/java/org/apache/camel/issues/ExceptionTest.java

I made some minor refactorings to reuse ContextTestSupport to make the
test case a little simpler & easier to read.

However the test case works fine for me when using the exception
handler and when not.

i.e. the message never carries on to the final "mock:result" and the
exception handler makes it go to "mock:exception". When not using the
exception handler I see the dead letter queue deliver to the default
URI (namely to log an ERROR in log4j)

Am using trunk though - I wonder how to reproduce this issue? Were you
using 1.1.0?

-- 
James
-------
http://macstrac.blogspot.com/