Hi Mandy

In this case, an exception is thrown from a custom CXF out interceptor (not part of the out JAX-RS chain) and as we discussed earlier, the mapping of such exceptions is not supported in earlier CXF versions, but only starting from CXF 2.7.8 (see the link I posted in another message).

However in this case in the default mapping won't help because RuntimeException is thrown, CXF JAX-RS only has a default WebApplicationException mapper.

Now, assuming it is CXF 2.7.8(-SNAPSHOT) and if no ExceptionMapper is available, or earlier CXF version, then we have a not-mapped exception escaping as per JAX-RS spec rules, with HTTP you'd get 500 indeed, but with LocalTransport you have that RuntimeException escaping directly into the client.

In my tests I was not getting NPE, I was getting the original RuntimeException wrapped in a client exception, but that is not good enough because I agree you should get a populated Response with 500 status,

Given that it is LocalTransport direct dispatch client which has an escaped server exception, the only way to intercept it internally and adapt to JAX-RS Response is to use in fault interceptors on the client side, which as it happens have not been supported by JAX-RS client runtime before :-), so we looked at how it can be done initially and now it is supported starting from CXF 2.7.8 as well, see this test:

http://svn.apache.org/repos/asf/cxf/trunk/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSLocalTransportTest.java

#testProxyServerInFaultDirectDispatch
#testProxyServerOutFault()

Note, the out fault is actually mapped correctly, the in fault interceptor is not even needed there, only needed in #testProxyServerInFaultDirectDispatch

Cheers, Sergey

On 29/09/13 22:37, Mandy Warren wrote:
Hi,

I am running some unit tests using local transport to see what happens when
an interceptor throws a Fault. I was expecting to get a Response back with
a status code of 500 but instead I get this:

javax.ws.rs.client.ClientException: java.lang.NullPointerException
     at
org.apache.cxf.jaxrs.client.AbstractClient.setResponseBuilder(AbstractClient.java:374)
     at
org.apache.cxf.jaxrs.client.WebClient.handleResponse(WebClient.java:1101)
     at
org.apache.cxf.jaxrs.client.WebClient.doResponse(WebClient.java:1088)
     at
org.apache.cxf.jaxrs.client.WebClient.doChainedInvocation(WebClient.java:1038)
     at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:858)
     at org.apache.cxf.jaxrs.client.WebClient.doInvoke(WebClient.java:832)
     at org.apache.cxf.jaxrs.client.WebClient.invoke(WebClient.java:395)
     at org.apache.cxf.jaxrs.client.WebClient.get(WebClient.java:574)


My test setup is as follows:-

I declare a DummyInterceptor which throws a Fault..

public class DummyInterceptor extends AbstractPhaseInterceptor<Message> {

     public DummyInterceptor() {
         super(Phase.MARSHAL);
     }

     public void handleMessage(Message message) throws Fault {
         throw new Fault(new RuntimeException("hello from runtime
exception"));
     }
}


My test case configures local transport & registers the DummyInterceptor

     @Before
     public void setup() {
         // enable local transport
         bus = BusFactory.newInstance().createBus();
         LocalTransportFactory localTransport = new LocalTransportFactory();
         DestinationFactoryManager dfm = bus
                 .getExtension(DestinationFactoryManager.class);
         dfm.registerDestinationFactory("
http://schemas.xmlsoap.org/soap/http";,
                 localTransport);
         dfm.registerDestinationFactory(
                 "http://schemas.xmlsoap.org/wsdl/soap/http";,
localTransport);
         dfm.registerDestinationFactory(
                 "http://cxf.apache.org/bindings/xformat";, localTransport);
         dfm.registerDestinationFactory(
                 "http://cxf.apache.org/transports/local";, localTransport);

         ConduitInitiatorManager extension = bus
                 .getExtension(ConduitInitiatorManager.class);
         extension.registerConduitInitiator(
                 "http://cxf.apache.org/transports/local";, localTransport);
         extension.registerConduitInitiator(
                 "http://schemas.xmlsoap.org/wsdl/soap/http";,
localTransport);
         extension.registerConduitInitiator(
                 "http://schemas.xmlsoap.org/soap/http";, localTransport);
         extension.registerConduitInitiator(
                 "http://cxf.apache.org/bindings/xformat";, localTransport);

         // create a local endpoint
         sf = new JAXRSServerFactoryBean();
         sf.setBus(bus);
         sf.setAddress(LOCAL_ADDRESS);
         sf.setServiceBean(new SimpleRestServiceImpl());
         sf.setServiceClass(SimpleRestServiceImpl.class);
     }

     @After
     public void teardown() throws Exception {
         if (null != jaxrsServer) {
             // explicitly stop server
             jaxrsServer.destroy();
         }
         if (null != bus) {
             // shutdown the bus
             bus.shutdown(false);
         }
     }

     @Test
     public void
testExceptionWhichOccursWithinAnOutboundFrameworkInterceptorReturnsAppropriateException()
             throws Exception {

         // register the DummyInterceptor which throws an exception
         List<Interceptor<? extends Message>> outInterceptors = new
ArrayList<Interceptor<? extends Message>>(
                 1);
         outInterceptors.add(new DummyInterceptor());

         sf.setOutInterceptors(outInterceptors);

         // start the server
         jaxrsServer = sf.create();

         WebClient client = WebClient.create(LOCAL_ADDRESS);
         WebClient.getConfig(client).getRequestContext()
                 .put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);

         try {
             Response response = client
                     .path("v1/greetings/aveeeeename")
                     .type(MediaType.APPLICATION_JSON)
                     .accept(MediaType.APPLICATION_JSON)
                     .get(Response.class);
             assertEquals(500, response.getStatus());
         } finally {
             if (null != client) {
                 client.close();
             }
         }
     }


I am using apache cxf version 2.7.4

Any help much appreciated

Thanks

Mandy



--
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Reply via email to