I understand that a Jersey-based web service is able to associate exceptions thrown by service methods to desired HTTP return codes (here). Now, is there any chance to make the client generate exactly the same exception that was generated by the service method? I mean, if the server side throws MySpecificException, is there a way to store such information (i.e., the FQN of the exception class) in the HTTP response (automatically, I don't want to turn to methods that build the response explicitly, I want them to return POJOs or void), so that the client can use it to re-throw the same exception?
-
[Duplicated](http://stackoverflow.com/questions/15185299/jax-rs-jersey-exceptionmappers-user-defined-exception) – thar45 Sep 06 '13 at 09:11
-
I don't think it's a duplication of that issue. Here I mean that I want the client to be able to know that the server generated UserNotFoundException, not just 404. I need this because I have several reasons for generating the FORBIDDEN HTTP code (eg, not authenticated user, user with insufficient privileges) and I don't want to rely on the error message to understand the details on the client side. – zakmck Sep 06 '13 at 10:09
1 Answers
REST does not specify exception as a response and thus there's no straightforward way to do this (this is not RPC).
However, you can introduce your own convention. For example:
On the provider side you could define ForbiddenException
:
public class ForbiddenException extends WebApplicationException {
public ForbiddenException(String code, String readableMessage) {
super(Response.status(Status.FORBIDDEN).entity(new ForbiddenEntity(code, readableMessage)).build());
}
}
(You should probably compose response in ExceptionMapper instead of exception itself, but this is just for demonstration purposes).
And on the consumer side - ClientFilter
:
public class ForbiddenExceptionClientFilter extends ClientFilter {
@Override
public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
ClientResponse response = getNext().handle(cr);
if (response.getStatus() == Status.FORBIDDEN.getStatusCode()) {
ForbiddenEntity reason = response.getEntity(ForbiddenEntity.class);
throw new RemoteResourceForbiddenException(reason.getCode(), reason.getReadableMessage());
}
return response;
}
}
This works as long as server complies with the convention and client uses the client filter.
Please note, this is not "exactly the same" exception - stacktrace is not transferred, however this is the right thing to do as it does not make any sense in client application. If you need stacktrace - it should be printed to logs using ExceptionMapper
on server side.

- 2,910
- 2
- 26
- 36
-
Thanks Jonas, this is what I'm doing indeed. However, it could be slightly better if there is was way (response headers? Cookies?) to equip the response with the name of the FQN of the exception that occurred. This would still be conventional and non-standard, but useful. Maybe there is already some de-facto convention like this? – zakmck Sep 10 '13 at 14:30
-