I'm calling out to a WS using cxf:cxfEndpoint and its working fine. I want to catch any exceptions using onException or something similar. For some reason its not working. I have set the dataFormat to PAYLOAD, handleFault attribute on the route and/or the camel context to true. The web service is not running so I'm expecting the exception to be caught but its not working. Same issue with unmarshalling of the XML.
When I throw an exception using it gets caught successfully using java.lang.Exception and written to my dummy exception queue... but when the webservice is down or I pass in some invalid XML and the marshalling fails then an exception gets thrown but not caught.
Is there anything else to be aware of?
EDIT: Included the code for unmarshaling. Switched to using Try/Catch and when i pass in invalid XML the exception does get caught during the junit testing but does not get caught at runtime
<route>
<from uri="jmsamq:In"/>
<doTry>
<unmarshal>
<jaxb contextPath="outbound.message"/>
</unmarshal>
<doCatch>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<transform>
<simple>Mapping Failed</simple>
</transform>
<to uri="jmsamq:errorqueue1"/>
</doCatch>
</doTry>
<log message="${body}"/>
<multicast stopOnException="true">
<to uri="direct:webservice"/>
<to uri="direct:myqueue"/>
</multicast>
</route>
the incorrect camel-context XML file was being used at runtime.. ignore question!
Related
I noticed that after successful doTry/doCatch handling global onException handler is no longer invoked. Here's my sample code:
<doTry>
<to uri="direct:triggerError"/>
<doCatch>
<exception>com.foo.bar.MyException</exception>
<log message="IN DOCATCH"/>
</doCatch>
<doFinally>
<log message="IN FINALLY"/>
</doFinally>
</doTry>
<throwException message="Now handle it in global handler" exceptionType="com.foo.bar.MyOtherException"/>
And in my camel context I have this:
<onException>
<exception>com.foo.bar.MyOtherException</exception>
<handled>
<constant>true</constant>
</handled>
<log message="HANDLING MY OTHER EXCEPTION"/>
<to uri="direct:commonAPIErrorProcessor"/>
</onException>
What I observe is the exception is properly caught in doCatch and doFinally is invoked, but the global onException is never called and I get a stack trace in response. How can I fix it?
I tried it with Camel 3.4.0 and 3.7.0, same results.
The problem in your example is that you call another route within doTry. This seems to confuse the Camel no matter if you use XML or Java DSL (in both DSLs the same effect).
As long as you use simple "statements" in doTry, everything works perfect. When you call another route, it is as you describe very confusing.
Camel catches the exception thrown by the other route, but afterwards the error handler stays "disabled". It seems like Camel loses the doTry scope and therefore never finishes the "error handling disabled state" that is enabled by doTry.
I therefore assume that the "route jump" is not the intended use case for doTry/doCatch. Since it overwrites the normal error handling, it should probably be used only very locally within a route.
So I have the following route (Camel 2.20.0)
I was working on a global <onException> block for a new route. For some reason it wasn't firing, so I moved the items to a doTry/doCatch within one specific route just to play with the error handeling.
<camelContext xmlns="http://camel.apache.org/schema/spring" id="jobfeedCamelContext">
<route id="testError">
<from uri="timer://runOnce?repeatCount=1&delay=5000" />
<doTry>
<throwException exceptionType="java.lang.Throwable"/>
<to uri="errorBean"/> <!-- bean does nothing but explicitly throws java.lang.Throwable -->
<doCatch>
<exception>java.lang.Throwable</exception>
<log message="### exception" />
</doCatch>
</doTry>
<log message="### out of try" />
</route>
</camelContext>
For output I get the stack trace from the beans java.Lang.Throwable (but no stacktrace is generated for the<throwException exceptionType="java.lang.Throwable"/>. I do not get my "### exception" log entry in any scenario, but I do get the "### out of try" log entry.
Have used this functionality in other routes on older version of camel, so I can't really see where I am going wrong. Anyone have any ideas? I've turned on route tracing and there is nothing helpful.
<throwException exceptionType="java.lang.Throwable" message="some text"/>
After upgrading from Camel 2.1 to 2.17 and some code modification we are having some problems with the exception handling in Camel. We send message from app A to app B. The happy flow works fine, but the unhappy flow doesn't.
We send the message to cause an exception but it is not correctly handled in the onexception block.
Actually, we see the following tracelog: ProcessTaskEx - message received, but I don't see: ProcessTaskEx - exception
The exception we get from Camel is:
camel exchange failed without an exception: <SOAP-ENV:Fault xmlns:SOAP-ENV>
Our route looks like this, any idea what the problem could be? Thank you very much for your time community! :)
<?xml version="1.0" encoding="ASCII"?>
<routes xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="switchyard://ProcessTaskEx"/>
<log message="ProcessTaskEx - message received: ${body}" loggingLevel="DEBUG" logName="WebServiceQueues" />
<to uri="switchyard://RequestCapacity"/>
<onException>
<exception>java.lang.Exception</exception>
<exception>webservicequeues.utilities.WebServiceQueueException</exception>
<log message="ProcessTaskEx - exception" loggingLevel="DEBUG" logName="WebServiceQueues" />
<redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="60000" maximumRedeliveryDelay="900000" retriesExhaustedLogLevel="INFO" retryAttemptedLogLevel="INFO"/>
<handled>
<constant>true</constant>
</handled>
<log message="Failed after Retry.Sending ProcessTask Request to Error Queue" loggingLevel="ERROR" logName="WebServiceQueues" />
<to uri="switchyard://ErrorProcessTaskExQueue"/>
</onException>
</route>
</routes>
As fas as I remember, faults are not handled by default. In order to enable this a property must be set: handleFault="true". It can be set for the whole Camel context or for individual routes.
Example for a route in XML:
<route handleFault="true">
...
</route
I read the corresponding documentation but I couldn't figure out why my Exception is not catched.
This is my route configuration:
<route id="foo">
<from uri="vm://.../>
<doTry>
<to uri="jetty:http://127.0.0.1:123/foo?restletMethod=PUT"/>
<to uri="ejb:java:global/..?method=method1(${body}, ${headers})"/>
<to uri="ejb:java:global/..?method=method2(${body}, ${headers})"/>
<doCatch>
<exception>java.lang.Exception</exception>
<transform>
<simple> ${exception.message} </simple>
</transform>
<to uri="smtp://... />
</doCatch>
</doTry>
</route>
Now when the JettyClient is not reachable a org.apache.camel.CamelExchangeException is thrown,
the route terminates and I receive an email. This is the desired behaviour.
But when method1 throws an exception it is not catched, hence the route continues and
I don't receive an email.
How can I make camel recognize and handle the exception in the second case too?
Solution: Make sure the exception isn't thrown inside a try-catch block -.-
This is stated in the documentation:
http://camel.apache.org/try-catch-finally.html
Camel error handling is disabled
When using doTry .. doCatch .. doFinally then the regular Camel Error
Handler does not apply. That means any onException or the likes does
not trigger. The reason is that doTry .. doCatch .. doFinally is in
fact its own error handler and that it aims to mimic and work like how
try/catch/finally works in Java.
You are probably better off to write it like this:
.doCatch(Exception.class)
// and catch all other exceptions
// they are handled by default (ie handled = true)
.to("direct:error")
In direct:error you can specify what to do in case something goes wrong.
I'm trying to retrieve the stacktrace from the onException handler in Apache Camel:
<onException>
<exception>java.lang.Exception</exception>
<handled>
<constant>true</constant>
</handled>
<setHeader headerName="exception">
<simple>${exception}</simple>
</setHeader>
</onException>
However, the above only shows the exception rather than the entire stacktrace.
I understand that Camel stores the caught exception as a property on the Exchange with the key: Exchange.EXCEPTION_CAUGHT, but how can this be retrieved from the camel context routes file ?
Use exception.stacktrace to get the stacktrace. See the variables listed in the table at this page: http://camel.apache.org/simple
<simple>${exception.stacktrace}</simple>
There is also a ${exception.message} to refer to the exception message itself.