Thanks for the reply! I've looked into this problem in great detail now. I've
downloaded, built and debugged the source. Along the way, I wrote some code
very similar to your code above. It works fine if you use the direct
transport. But I think you'll find that it does not work if you change the
transport to JMS (Note I'm using Camel 1.3.0).

If you look at the JmsBinding.makeJmsMessage method, an exception on the
Exchange object never becomes part of the JMS message returned to the reply
queue. It simply gets thrown away. I've come up with an initial workaround
by subclassing JmsComponent and JmsBinding.

----------------------
public class MyJmsComponent extends JmsComponent {

    @Override
    protected Endpoint<JmsExchange> createEndpoint(String uri, String
remaining, Map parameters) throws Exception {
        JmsEndpoint endpoint = (JmsEndpoint)super.createEndpoint(uri,
remaining, parameters);
        
        endpoint.setBinding(new MyJmsBinding());
        
        return endpoint;
    }
}

public class MyJmsBinding extends JmsBinding {

        public MyJmsBinding() {
        }

        @Override
        public Object extractBodyFromJms(Exchange exchange, Message message) {
                Object object = super.extractBodyFromJms(exchange, message);
                
                if (object instanceof Throwable)
                        throw new RuntimeException((Throwable)object);
                
                return object;
        }
        
        @Override
        public Message makeJmsMessage(Exchange exchange, 
org.apache.camel.Message
camelMessage,
                Session session) throws JMSException
        {
                Message answer = null;
                if (camelMessage instanceof JmsMessage) {
                        JmsMessage jmsMessage = (JmsMessage) camelMessage;
                        answer = jmsMessage.getJmsMessage();
                }
                if (answer == null) {
                        if (exchange.getException() != null) {
                                answer = 
createJmsMessage(exchange.getException(), 
                                        session, exchange.getContext());        
                        
                        }
                        else {
                                answer = 
createJmsMessage(camelMessage.getBody(), session,
exchange.getContext());
                        }
                        
                        appendJmsProperties(answer, exchange, camelMessage);
                }
                return answer;
        }
}

----------------------

This results in the behavior that I was looking for, but still isn't exactly
right because it DOES throw the exception rather than just leave it as in
the exception field on the Exchange. The other problem that I can see is if
the Exception thrown is not in client's class path, there might be problems
deserializing it on the other side. 

I'm not sure why the camel developer's chose not to throw these exceptions
when calling the template.sendBody methods (for the direct transport). If
you want to see the details of the exception thrown (or the request and
response are the same type), you cannot use the sendBody methods of
CamelTemplate or the even simpler approach of using ProxyHelper.
-- 
View this message in context: 
http://www.nabble.com/Handling-Bean-exceptions-tp17671948s22882p17690144.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Reply via email to