0

I am using Camel to read off a JMS queue and place on a SEDA queue, which then gets read by a separate route and processed. Sometimes if something goes wrong in my application my SEDA queue fills up, and I get:

java.lang.IllegalStateException: Queue full

This makes sense. I want to catch this exception, so I can stop the route that is subscribing to JMS (to stop any more messages from coming in), but I don't seem to be able to catch it.

This is my route (simplified):

from("{{jms.loader.in}}") 
.setExchangePattern(ExchangePattern.InOnly)
.routeId(this.getClass().getSimpleName())
.to("seda://JmsFetchRoute_incoming);

I tried to surround it in a doTry - doCatch, but the exception was not caught:

from("{{jms.loader.in}}") 
.setExchangePattern(ExchangePattern.InOnly)
.routeId(this.getClass().getSimpleName())
.doTry()
    .to("seda://JmsFetchRoute_incoming)
.doCatch(Exception.class)
    .log(LoggingLevel.ERROR, "Your queue is full!")
.end();

It seems no matter what I try and do in the 'doCatch' block, it never reaches this point. So how can I wrap the 'call' to the SEDA queue such that I can catch the Queue Full exception?

EDIT1

As per hveiga's answer, I also tried creating an ErrorHandlingRoute with 'onException' and adding that to my context, but that also didn't pick it up:

@Override
public void configure() throws Exception {
    onException(IllegalStateException.class)
        .handled(true)
        .log(LoggingLevel.ERROR, "Exception route stopping topic route, SEDA queue full")
        .to("controlbus:route?routeId=JmsFetchRoute&action=stop")
    .end();
}

I also added it to my fetch route, still didn't pick it up:

from("{{jms.loader.in}}") 
.setExchangePattern(ExchangePattern.InOnly)
.routeId(this.getClass().getSimpleName())
    .onException(IllegalStateException.class)
      .handled(true)
      .log(LoggingLevel.ERROR, "Topic consumer stopping route, SEDA queue full : " + this.getClass().getSimpleName())
      .to("controlbus:route?routeId="+this.getClass().getSimpleName()+"&action=stop")
    .end()
.to("seda://JmsFetchRoute_incoming);

EDIT2

According this post the onException can not be defined in a separate RouteBuilder...

EDIT3

Still no luck getting an exception caught from inside the same routebuilder, so I gave my 'onException' route a name but this name is not in the 'routes' part of Camel when checked in JMX?? Is there a config I need to turn on to enable 'onException' routes?

Community
  • 1
  • 1
Matt
  • 3,303
  • 5
  • 31
  • 53

2 Answers2

1

I think you are looking for onException(). This feature of camel will catch any exception of the type you specify and will let you handle it the way you prefer. It seems that you want to catch that exception and the stop the route using the Control Bus component.

It would be something like:

onException(IllegalStateException.class).
handled(true).
to("controlbus:route?routeId=yourRouteId&action=stop");

For more info, please take a look to:

hveiga
  • 6,725
  • 7
  • 54
  • 78
  • Thanks hveiga, this looks promising. I had assumed that onException would work the same as doTry...doCatch, but it seems that since it applies to the whole camel context (when global scope) it should pick up errors no matter where they are thrown. I will test later and let you know if this solves my problem. I hadn't seen the controlbus component (look like it's new) - very nice! – Matt Feb 08 '14 at 10:36
  • iirc, onException can either apply to the whole camel context, or be defined within a route to apply for the rest of that route. Controlbus is new in 2.12. Prior to that, you can do the same thing with beans via the CamelContext. – vikingsteve Feb 08 '14 at 15:23
  • It didn't work :( I created a new route 'ErrorHandlingRoute' which basically has your code above, plus some logging), added that to my camelcontext (apparently it has to be the first route added before any others), but the exception still comes through in the logs as a runtime exception with a full stack trace and my log messages in my exception aren't printed... any suggestions? I also added it to my route (so I have a route one AND a global one, and neither of them picked it up) – Matt Feb 10 '14 at 11:37
0

This appears to have been fixed in 2.13.0. I can't find a bug report, but I see the same issue as hveiga in 2.12.3. In 2.13.0 onException and doTry/doCatch can be used to handle a queue full error.

jbarrus
  • 325
  • 2
  • 5
  • I remember debugging this issue, and eventually worked it out (apologies, just realised I never posted back here). The queue full never actually throws the exception - it prints a stack trace, which makes it look like an exception is being thrown, but this exception is never propagated back to camel (thus, never caught by the onException code). Eventually I just wrote my own separate route on a timer that checks the size of the queue against the 'max queue size' property I have set – Matt Jun 26 '14 at 09:30