Chris
Chris

Reputation: 5654

JAX RS CXF Interceptor for throwing client specific exceptions

I have a server exposing set of classes as RESTful services. I understand that we could use ExceptionMapper for passing the exception to the client. There are few checked-exceptions that are shared between client and server. However in some of my services, I have few checked-exceptions which are not available in client JVM.

I understand that changing the endpoint to make sure that the checked-exception is handled properly fixes the issue.

But, I would like to do it at interceptor layer for two reasons:

Looking at CXF documentation, I understand that I have to extend AbstractPhaseInterceptor and override handleMessage()

public class MyOutExceptionInterceptor extends AbstractPhaseInterceptor<Message> {

    public AttachmentInInterceptor() {
        //Which phase to call here ??
        super(Phase.POST_INVOKE);
    }

    public void handleMessage(Message message) {

        //Check from message that it contains an exception of MyCheckedException.class
        //Create an exception that client can understand

    }
}

How do I do this ?

Thanks in advance.

Upvotes: 0

Views: 2568

Answers (2)

Gunslinger
Gunslinger

Reputation: 747

I know I'm late but I also had this problem and came up with this solution. So for future reference:

Override handleFault instead, inside:

Exception fault = message.getContent(Exception.class);
Exception exception = fault.getCause();
YourOwnFault newFault = new YourOwnFault("bla bla bla");
message.setContent(Exception.class, newFault);

In other words: extract the fault, get the exception as the cause, create a new fault and insert int.

Upvotes: 1

mucher
mucher

Reputation: 11

Try something like:

public void handleMessage(Message message) {
 // Map exception
    Exception exception = message.getContent(Exception.class);
    Exception mappedException = mapper.map(exception);

    Fault fault = exception instanceof Fault ? (Fault) exception : null;
    if (fault == null)
    {
        fault = new Fault(exception);
        message.setContent(Exception.class, fault);
     }
    fillInFaultDetails(fault, exception);
}

This is actually a snippet from our code (I omitted the mapping/filling in detaisl for brevity; key things to do is to replace the message content.). As for the phase - we run it at POST_LOGICAL; POST_INVOKE may work as well.

By the way - not sure what's your use case, but I don't like using faults to communicate business exceptions (in my mind faults indicate a general message processing error rather than a business logic exception.

Upvotes: 0

Related Questions