Eu também estou olhando isso. O que o renanreismartins disse não é inteiramente verdade. A questão é que, pela exception não se propagar para o cliente (pois pode estar em outra linguagem), você acaba tendo que mapear essa exception no servidor e remonta-la no cliente.
Por exemplo, eu fiz uma classe que mapeia os dados de uma exception, algo bem simples. Segue:
public class BusinessExceptionMapper implements ExceptionMapper<BusinessException> {
public Response toResponse(BusinessException exception) {
ExceptionMapping em = new ExceptionMapping();
em.setType(exception.getClass().getName());
em.setMessage(exception.getMessage());
String rootCause = null;
String rootMessage = null;
Throwable t = null;
while ((t = exception.getCause()) != null) {
rootCause = t.getClass().getName();
if (t instanceof Exception) {
Exception e = (Exception) t;
rootMessage = e.getMessage();
}
}
em.setRootCause(rootCause);
em.setRootMessage(rootMessage);
return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
.entity(em).build();
}
}
Com isso, estou criando (no meu caso em JSON) uma resposta baseada na classe:
@XmlRootElement
public class ExceptionMapping {
private String type;
private String message;
private String rootCause;
private String rootMessage;
//gettes e setters
}
A resposta do servidor ficou assim (quando a exceção acontece):
Estou usando Spring com CXF, então, para mapear o ExceptionMapper, ficou assim:
<jaxrs:server id="restServer" address="/">
<jaxrs:serviceBeans>
<ref bean="bookService" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.foo.rest.app.BusinessExceptionMapper" />
</jaxrs:providers>
</jaxrs:server>
Depois vem a parte do Client. Eu estou trabalhando nela agora. Ainda não consegui achar uma solução que funcione 100%, mas vou passar em que pé estou.
Criei o ExceptionMapper aqui também, mas nesse caso é o ResponseExceptionMapper, que faz o trabalho contrário do anterior, transformando a response em exception:
public class MeuResponseExceptionMapper implements ResponseExceptionMapper<BusinessException> {
@Override
public BusinessException fromResponse(Response r) {
System.out.println("FROM RESPONSE!!!!");
r.getEntity();
return new BusinessException("MINHA MSG AQUI");
}
}
Esse código está bem porquinho pois estou debugando pra ver se passa por aí (não consegui fazer passar ainda). Eu mapeei o MeuResponseExceptionMapper da seguinte maneira:
<jaxrs:client id="bookService"
address="http://localhost:8082/poc-rest-cxf/services/bookService"
serviceClass="org.foo.web.services.BookService"
inheritHeaders="true">
<jaxrs:providers>
<bean class="org.foo.web.factory.MeuResponseExceptionMapper"></bean>
</jaxrs:providers>
</jaxrs:client>
Mesmo principio do server, mas no jaxrs:client.
Lendo referências na internet, vi o seguinte:
Mas o meu não está sendo chamado… A partir daqui, se alguém poder ajudar a fazer funcionar, agradeço ^^