14
votes

I have a simple client using RESTEasy as follows:

public class Test {
    public static void main(String[] args) {
        ResteasyClient client = new ResteasyClientBuilder().build();
        ResteasyWebTarget target = client.target("http://localhost");
        client.register(new MyMapper());
        MyProxy proxy = target.proxy(MyProxy.class);
        String r = proxy.getTest();
    }
}

public interface MyProxy {
   @GET
   @Path("test")
   String getTest();
}

@Provider
public class MyMapper implements ClientExceptionMapper<BadRequestException>{

    @Override
    public RuntimeException toException(BadRequestException arg0) {
        // TODO Auto-generated method stub
        System.out.println("mapped a bad request exception");
        return null;
    }

}

The server is configured to return a 400 - Bad Request on http://localhost/test along with a helpful message. A BadRequestException is being thrown by ClientProxy. Other than wrapping in try/catch, how can I make getTest() catch the exception and return the Response's helpful message as a string. I tried various ClientExceptionMapper implementations, but just can seem to get it right. The above code doesn't ever call toException. What am I missing here?

My current work-around is to use a ClientResponseFilter and then do a setStatus(200) and stuff the original status in the response entity. This way I avoid the exception throws.

2
Can you explain what you mean by "The server is configured to return a 400 - Bad Request"? My thought is that the implementation of MyProxy.getTest() should actually be throwing an exception which contains a helpful message. Then you would use an ExceptionMapper to map that exception to a 400 - Bad Request response (and you could include the message as the body of the response).FGreg
Read the first sentence of my question. I'm writing a client, not the server.gogators

2 Answers

0
votes

I'd advise going through the Jax-RS client API unless there's a functionality you need using the RestEasy clients. (RestEasy ships with Jax-RS, so there's no library differences)

Client client = ClientFactory.newClient();
WebTarget target = client.target("http://localhost/test");
Response response = target.request().get();
if ( response.getStatusCode() != Response.Status.OK.getStatusCode() ) {
    System.out.println( response.readEntity(String.class) );
    return null;
}
String value = response.readEntity(String.class);
response.close();

The reason why your mapper does not work is because the client is not actually throwing the exception. The client is returning a valid result to the proxy, and the proxy is reading that, and throwing the exception, which happens after the mapper can intercept it.

0
votes

ClientExceptionMapper in Resteasy is deprecated (see java docs)

The JAX-RS 2.0 client proxy framework in resteasy-client module does not use org.jboss.resteasy.client.exception.mapper.ClientExceptionMapper.

Try with an ExceptionMapper like this:

import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class MyMapper implements ExceptionMapper<ClientErrorException> {

    @Override
    public Response toResponse(ClientErrorException e) {
        return Response.fromResponse(e.getResponse()).entity(e.getMessage()).build();
    }
}

Regards,