camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "James Strachan" <>
Subject Re: Exception based routing
Date Tue, 07 Aug 2007 07:08:15 GMT
On 8/7/07, Neil Thorne <> wrote:
> Hi Neil
> Hi James thanks for the quick reply.
> >> a) a system exception gets thrown. A system exception indicates an
> >> infrastructure problem that will be fixed ASAP as it is essential to the
> >> correct functioning of the system as a whole. eg. jdbc connection failed,
> >> remote system is down etc. If a system exception is thrown then that
> >> operation should be continually retried until it is successful.
> >>
> >> b) a business exception is thrown. A business exception indicates that
> >> there
> >> was a problem with the request itself. It should not be retried (at least
> >> not until the problem has been resolved). The message should be moved
> >> onto a
> >> hospital queue where it can be inspected, changed and retried after
> >> possible
> >> manual intervention.
> > BTW how can you tell the difference between a) and b)? Are there
> > certain base exception types you can use?
> Yes I can. Although our applications can throw quite a few different
> exceptions, so far in terms of routing we only need these two base types. We
> have translators that convert the original exception to one of these types.

Ah cool. I was wondering; rather like the Type Converter stuff....

Do we need a simple little framework where we can easily mark
exception types as being 'system exceptions' or 'business exceptions';
so the error handler can do the right thing by default without
explicit configuration in the DSL?

e.g. for code you own, we could add an @BusinessException or
@SystemException annotation. The annotation could even configure the
retry count/timeout to be specified on a per exception basis.

For code that we don't own, we could add some kinda
META-INF/services/org/apache/camel/BusinessExceptions file that lists
the base classes of all the business level exceptions (or system
exceptions etc).

Am thinking btw that it might be easier to mark just the business
level exceptions; as the system exceptions tend to be more diverse &
harder to enumerate.

If we could know using the 'ExceptionRepository' what exceptions are
which, then we can know whether or not to retry etc.

Am even thinking, maybe we could attach different error handling to
certain types of exception. e.g. if we can ever really detect a true
database deadlock (which is getting harder these days due to exception
wrapping etc) - we might want to increase the retry counts etc.

> >> What is the simplest way to achieve this with camel? Currently I can only
> >> see an errorHandler which assumes you want to dump messages that cannot
> >> be
> >> processed to an error endpoint.
> >An ErrorHandler could do anything - e.g. based on the type of
> >exception it could decide whether or not to retry (if at all) etc.
> >The default implementation is DeadLetterChannelErrorHandler, which
> >assumes n-retries with optional backoff delays - before sending to a
> >'dead letter' endpoint, which is kinda like your hospital queue
> Okay I can write my own implementation.

Please let us know how you get on - as I'd love something like this to
be in the core of Camel.

e.g. maybe we can patch the default DeadLetterChannelErrorHandler to
use some kinda pluggable strategy to determine if an exception is a
business level exception (and so the retry logic is not used etc)

> We're using the Java DSL style of
> configuration.
> I'd need to set two different retry strategies depending on the type of
> exception.
> from("direct:a").errorHandler().filter(
> type.isEqualTo("com.acme.BusinessException").
> maximumRedeliveries(0).to("direct:business.errors")
> ).errorHandler().filter(
> type.isEqualTo("com.acme.SystemException").
> maximumRedeliveries(-1).useExponentialBackOff()
> ).to("direct:b");

Looks good :)

> Without explicit DSL support I'm wondering about the custom ErrorHandler
> impl, and what the current DSL
> would have to look like. I don't have to specify any endpoint for the
> ErrorHandler right?

The current default error handler uses any-old-processor as the dead
letter queue; so you could configure separate endpoints depending on a
system or business exception; but maybe you just wanna change the
properties (retry count / backoff times etc) and leave the default

> In that case I could just manually post messages to the "business exception"
> endpoint if the exception type matches using a spring configured proxy, or
> otherwise just go into an infinite loop. I'll read the source for
> DefaultErrorHandler to get a better understanding of the ErrorHandlers in
> general.

I'm even wondering if the DSL should have exception handling as a core
feature. I guess we can either, add routing/filtering inside a
specific error handler; or we could add explicit error-handling
routing constructs.

> >Firstly you can customize the errorHandler on a set of routes, or a
> >specific route, or within the processing of a route. So if you had
> >your own idea errorHandler implementation you could use it wherever
> >you like
> >Currently there's no 'exception-type-based error handler'
> >implementation; but it should be easy to add such a thing. e.g. we
> >could add a Set<Class> property to the DeadLetterChannel for
> >exceptions which should not be retried maybe?
> > If I could then I suppose I could move business exceptions immediately to
> > the hospital queue (with a retry count of zero).
> >
> > I could also bind a different error handler with an infinite retry count
> > (-1?).
> >Yeah - I've been pondering similar things. I'm wondering if we should
> >have some kinda version of the Content Based Router that uses a
> >similar notation to try/catch/finally; where known business related
> >exceptions are caught and the message forwarded to a 'business logic
> >failed' type endpoint, otherwise system exceptions (which are way more
> >random and harder to catch all) filter up to the default errorHandler
> >- such as for retrying & dead letter channels etc.
> >e.g. in XML I was pondering something like
> <try>
>   <!-- do some stuff here which may throw exceptions -->
>   <catch error="">
>     <!-- for business level exceptions, send to some reject queue -->
>     <to uri="activemq:myRejections'/>
>   </catch>
>   <!-- any other system exceptions cause the error handler to retry n-times
> -->
> </try>
> >Thoughts?
> yes this would also seem to do the trick. Would this style be supported in
> the Java DSL?

Ideally yes - both Java and XML

> I'm just going into the office. I'll be back in an hour or so. Hopefully the
> DSL above clarifies what we need.

Yes thanks! I've just woke up - a tad early - so need a bit more
coffee to ponder this a bit more; as I think there's a few ways we
could go, am currently not sure the best way (or if we should do all
of them :)

* we could have some kinda metadata registry thing, like the Type
Converter, to indicate what exceptions are really system exceptions
versus business exceptions, so that the default error handler can just
do the right thing (e.g. have default, or customizable retry counts by
type (business v system) or even customize by a specific exception
type etc

* we could add routing inside the error handler as you suggest

* we could add some kinda try/catch type construct to the DSL so that
the DSL itself can describe the routing & handling of exceptions

The last 2 are kinda similar in some ways. I guess each have strengths
and weaknesses; I kinda like simplifying the DSL as much as possible
and having things do the right thing without needing much explicit
coding (rather like the type conversion stuff); but sometimes making
the DSL totally explicit (e.g. in terms of error handling or type
conversion) can be useful.

Let me have more coffee & I'll get back to you :)

View raw message