cxf-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mandy Warren <mandys.in...@gmail.com>
Subject Re: Handling exceptions in a JAX-RS fault interceptor when using Local Transport
Date Thu, 19 Sep 2013 20:31:14 GMT
Many thanks this worked fine!

Sent from a mobile device

On 13 Sep 2013, at 17:31, Sergey Beryozkin <sberyozkin@gmail.com> wrote:

> Hi
> On 13/09/13 12:35, Mandy Warren wrote:
>> Many thanks for your reply. I am now using an ExceptionMapper for application errors
and have created a ResponseHandler to try an catch other interceptor exceptions but I can't
work out how to get hold of the exception from the objects passed into the handleResponse
method.
>> 
>> I tried doing message.getExchange().getOutMessage().getContent(Exception.class))
but no luck..
>> 
>> Please could you advise how this is possible?
> The problem is that the exceptions thrown from the CXF interceptors escape the JAX-RS
flow, ResponseHandler (or ContainerResponseFilter in CXF 3.0.0 SNAPSHOT) are part of the normal
out JAX-RS chain and they do not see those exceptions.
> 
> I'm presuming you throw the exceptions from CXF in interceptors, right ?
> Try replacing them with RequestHandler (or ContainerRequestFilter if on CXF 2.7.x)
> 
> I need to check if, optionally, we can handle the exceptions coming from other CXF in
interceptors via JAX-RS and effectively ignore or fault out chain...
> 
> Cheers, Sergey
> 
>> Many thanks
>> 
>> Sent from a mobile device
>> 
>> On 12 Sep 2013, at 21:05, Sergey Beryozkin <sberyozkin@gmail.com> wrote:
>> 
>>> Hi
>>> On 12/09/13 18:32, Mandy Warren wrote:
>>>> Hi,
>>>> 
>>>> I am trying to write a Fault Interceptor to handle exceptions both from my
>>>> application code & from other interceptors. The Interceptor needs to
change
>>>> the HTTP status code to something appropriate and set the message body with
>>>> info that explains the error in more detail (either in JSON or XML
>>>> depending on the request mime type).
>>>> 
>>>> Many of the examples I have seen modify the HttpResponse using code such
as:
>>>> 
>>>>  HttpServletResponse response = (HttpServletResponse) message
>>>>                 .getExchange().getInMessage()
>>>>                 .get(AbstractHTTPDestination.HTTP_RESPONSE);
>>>> 
>>>> however because we have integration tests which use the CXF local transport
>>>> rather than HTTP this code doesn't seem to work.
>>>> 
>>>> I need a solution which works for both HTTP & Local Transport.
>>>> 
>>>> Here's the code I have so far but I get a null pointer thrown as the
>>>> OutMessage seems to be null..
>>>> 
>>>> public class MyFaultInterceptor extends AbstractPhaseInterceptor<Message>
{
>>>>> 
>>>>>     public CAPTWOFaultInterceptor() {
>>>>>         super(Phase.PRE_STREAM);
>>>>>     }
>>>>> 
>>>>>     public void handleMessage(Message message) throws Fault {
>>>>> 
>>>>>         Exception ex = message.getContent(Exception.class);
>>>>> 
>>>>>         if (ex == null) {
>>>>>             LOGGER.debug("unexpected null exception");
>>>>>             throw new RuntimeException("Exception is expected");
>>>>>         }
>>>>>         if (!(ex instanceof Fault)) {
>>>>>             LOGGER.debug("unexpected exception type");
>>>>>             throw new RuntimeException("Fault is expected");
>>>>>         }
>>>>> 
>>>>>         Fault fault = (Fault)ex;
>>>>>         Throwable causingException = fault.getCause();
>>>>> 
>>>>>         LOGGER.debug("handling exception
>>>>> {}"+causingException.getClass().getName());
>>>>> 
>>>>>         if (causingException instanceof SomeBadException) {
>>>>>             Response response =
>>>>> Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
>>>>             // outMessage seems to be null!
>>>> 
>>>>             message.getExchange().getOutMessage().put(Response.class,
>>>> response);
>>>>         }
>>>> 
>>>>         message.getInterceptorChain().abort(); // not sure if I need this!
>>>>     }
>>>> 
>>>> 
>>>> 
>>>> Any help would be much appreciated!
>>> I think the only way to make it work in a portable way across multiple transports
is to work with JAX-RS 2.0 ExceptionMapper (for catching the exceptions) and also replace
the CXF interceptors with JAX-RS 2.0 in/out filters - this way it is guaranteed that JAX-RS
Response will be produced and thus it will work even for Local transport.
>>> 
>>> Using CXF interceptors in JAX-RS would also work with Local transport in normal
flows but the exceptions thrown from such interceptors can only be handled in fault interceptors,
where realistically you need to work with HttpServletResponse;
>>> 
>>> I'm not sure why an out message is null; that solution probably won't work anyway,
though may be we should look into it too; I'm not sure actually we have Local transport tests
dealing with JAX-RS server errors, I'll have a look
>>> 
>>> Sergey
>>> 
>>> 
>>>> Many thanks
>>>> 
>>>> Mandy
>>> 
>>> 
>>> --
>>> Sergey Beryozkin
>>> 
>>> Talend Community Coders
>>> http://coders.talend.com/
>>> 
>>> Blog: http://sberyozkin.blogspot.com
> 
> 
> -- 
> Sergey Beryozkin
> 
> Talend Community Coders
> http://coders.talend.com/
> 
> Blog: http://sberyozkin.blogspot.com

Mime
View raw message