15

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.

gogators
  • 783
  • 2
  • 6
  • 17
  • 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 Jun 04 '15 at 00:20
  • 1
    Read the first sentence of my question. I'm writing a client, not the server. – gogators Jun 04 '15 at 10:43

2 Answers2

1

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,

Ariel Carrera
  • 5,113
  • 25
  • 36
0

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.

Jeff Wang
  • 1,837
  • 1
  • 15
  • 29
  • 2
    Doesn't this throw out all the benefits of using the proxy though (for example /test is hardcoded in the example above)? I read the question as how to get the proxy to throw a more useful exception. It's strange to me that the proxy is returning an exception with a hard-coded message of "bad request" when the actual message is in the response. Is there an interceptor to wrap around the proxy's exception handling? – Michael Haefele Jun 30 '17 at 15:40
  • 4
    The fact that the proxy doesn't preserve any information about the underlying error is a pretty fatal flaw, IMHO. The only way around it I can see is to have the proxy's methods return Response, from which the caller can get the entity and/or the HTTP elements. But this means the entity return type is no longer specified in the interface. It's a shame. – Bampfer Sep 06 '18 at 16:06