Imagine there is a rest endpoint listening on host.tld/api
and which returns a 404 Not Found
with the following body:
{
"status": 404,
"message": "This is a custom error message",
"errorNr": 13400
}
Additionally there is a ClientResponseFilter which looks like this:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}
The client uses this code to retrieve the response of the rest endpoint:
WebTarget target = getTarget();
try {
return target.request(MediaType.APPLICATION_JSON_TYPE).get(MyCustomDTO.class);
} catch (Exception e) {
if (e.getCause() instanceof CustomException) {
// some other logic
}
}
The code must work with the jersey and the apache cxf JAX-RS implementation. Now take a look at the last code block. When using jersey I get a javax.ws.rs.ProcessingException
and executing e.getCause()
returns a CustomException
, so everything is correct. When using Apache CXF I get a javax.ws.rs.NotFoundException
with absolutely no information about the response body and where e.getCause()
returns null
. Why is there such a difference? And how can I fix that?
Just before you throw your exception, you can set the status code to 200, which will prevent CXF from throwing a NotFoundException
:
public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
if (responseContext.getStatus() != Response.Status.OK.getStatusCode()) {
// get the real error message
CustomExceptionData error = new ObjectMapper().readValue(
responseContext.getEntityStream(),
CustomExceptionData .class
);
responseContext.setStatus(Response.Status.OK.getStatusCode());
throw new CustomException(error.getErrorNr(), error.getStatus(), error.getMessage());
}
}