Search code examples
javajerseyjax-rsjersey-2.0jersey-client

How to catch WebApplicationException with JAX-RS


I am trying to catch WebApplicationException with my javax.ws.rs.ext.ExceptionMapper class but I get a strange behavior.

This is my simple rest method:

@GET
@Path("/saySomething")
public List<String> saySomething() {
    String response = EchoRestClient.ping();
    List<String> list = new ArrayList<>();
    list.add(response);
    list.add("okay");
    return list;
}

(1st) This is the client class which calls another rest api:

public class EchoRestClient {
    private static Client client = ClientBuilder.newClient();

    public static String ping() {
        String serviceUrl = PropertyReader.getProperty(ServiceUrl.ECHO_SERVICE);

        Response response = client
                .target(serviceUrl)
                .path("saySomething")
                .request(ExtendedMediaType.APPLICATION_UTF8)
                .get();

        if (response.getStatus() == Response.Status.OK.getStatusCode()) {
            return response.getEntity(String.class);
        }

        throw new WebApplicationException(response);
    }
}

And my custom Exception handler, which does NOT catch the above thrown exception:

@Provider
public class WebservletExceptionMapper implements ExceptionMapper<Exception> {
    @Override
    public Response toResponse(Exception exception) {

        System.out.println("caught exception");
        Response response;

        if (exception instanceof WebApplicationException) {
            response = ((WebApplicationException) exception).getResponse();
        } else {
            response = Response....build();
        }

        return response;
    }
}

(2nd) BUT if I do this the exception is caught (EchoRestClient.java):

public static String ping() {
    // same code then before

    WebApplicationException e = new WebApplicationException(response);
    throw new RuntimeException("xxxxxx", e);
}

My code above works fine and I get a proper response when I call the saySomething rest method from my web browser.

BUT if I undeploy the EchoService rest (contains the called ping rest method) the HTTP 404 is not caught in the 1st case. I need to throw a RuntimeException because WebApplicationException is not caught (2nd case).

According to the documentation the exception hierarchy is WebApplicationException extends RuntimeException.

What is wrong here?

-- EDIT --

If I throw this exception then it is caught fine: throw new WebApplicationException(response.getStatus())

But this one does not work: throw new WebApplicationException(response)

Is something wrong in the response object?


Solution

  • This is caused by an issue in Jersey. If your code throws a WebApplicationException that contains a Response object, ExceptionMappers are not called.

    See also: