Hi

I'm sorry for a late response.

This code line in JAXRSInInterceptor :

message.getExchange().put(Response.class, excResponse);

will result in a JAXRSInvoker returning without invoking a service and this
(exception mapper) response will be eventually handled by a
JAXRSOutInterceptor. 

So if you update your mapper to return a custom response in case of
WebApplicationException then it should work as expected

let me know please if you still have problems with customizing a
WebApplicationException response when it's thrown from JAXRSInInterceptor

cheers, Sergey


liw wrote:
> 
> Hi Sergey,
> 
> I can change my exception handler to create a custom response, but the
> problem here is that it doesn't even return the response to the user this
> in this case.
> 
> Here is the code snippet from JAXRSInIntercepter. It users the exception
> handler to convert the fault to response, but after that, it puts the
> response to the exchange. It then continues to invoke the next
> InInterceptor, which in our case there is a RuntimeException thrown by our
> custom InIntercepter. It then calls the fault interceptor handles the
> fault. Since our custom fault intercepter only handles SoapMessage, it
> returns a xml error response.
> 
> <ns1:XMLFault>
> <ns1:faultstring>
>    Endpoint method NULL
> </ns1:faultstring>
> </ns1:XMLFault>
> 
> 
> Code Snippet from JAXRSInIntercepter
> ===========================
>  public void handleMessage(Message message) {
>         
>         try {
>             processRequest(message);
>         } catch (RuntimeException ex) {
>             Response excResponse = JAXRSUtils.convertFaultToResponse(ex,
> message);
>             if (excResponse == null) {
>                
> ProviderFactory.getInstance(message).clearThreadLocalProxies();
>                 throw ex;
>             }
>             message.getExchange().put(Response.class, excResponse);
>         }
>     }
> 
> 
> Code Snippet from our Custom FaultInterceptor
> ===================================
> 
> 
> public void handleMessage(Message message) throws Fault {
>         if(message==null ||message.getExchange()==null ||
> message.getContent(Exception.class) == null ) {
>             log.error("Error processing fault. Error context missing.");
>             throw new StdRuntimeException("Unknown Error has Occurred.");
>         }
>         
>         if (message instanceof SoapMessage) {
>       
>               SoapMessage msg = (SoapMessage)message;
>               addHeader(msg, AppConstants.SID, AppUtils.getHostName());
>               addHeader(msg, AppConstants.STIME, new Date().toString());
>       
>               Fault fault = (Fault)message.getContent(Exception.class);
>               Throwable rootCause = fault.getCause()!=null ? fault.getCause() 
> :
> fault;
>               SoapFault sf = SoapFault.createFault(fault, msg.getVersion());
>               message.setContent(Exception.class, sf);
>                 . . .
>     
>         }
>     }
> 
> 
> 
> However, when an exception is thrown in the application code, the
> JAXRSInvoker.invoke() method converts the fault to response and returns a
> MessageContentsList. It marshals the response and return JSON response to
> user.
> 
> 
> code snippet from  JAXRSInvoker.invoke()
> =================================
> 
> catch (Fault ex) {
>             Response excResponse =
> JAXRSUtils.convertFaultToResponse(ex.getCause(), 
>                                                                     
> exchange.getInMessage());
>             if (excResponse == null) {
>                
> ProviderFactory.getInstance(exchange.getInMessage()).clearThreadLocalProxies();
>                 ClassResourceInfo criRoot =
>                    
> (ClassResourceInfo)exchange.get(JAXRSInInterceptor.ROOT_RESOURCE_CLASS);
>                 if (criRoot != null) {
>                     criRoot.clearThreadLocalProxies();
>                 }
>                 throw ex;
>             }
>             return new MessageContentsList(excResponse); 
> 
> 
> In the case of exception happens from interceptors, is there any way that
> we can return the response object back to user instead of invoking with
> the next interceptor?
> 
> is there any way we can enhance our existing fault interceptor and return
> a JSON response back to user?
> 
> Thanks a lot,
> 
> Li
> 
> 
> 
> Sergey Beryozkin-2 wrote:
>> 
>> Hi
>> 
>> Your exception handler recognizes that a WebApplicationException has
>> been thrown but the code block which creates a custom response is
>> skipped in such cases.
>> You may want to check the status code in such cases and if it's 404 then
>> also create a custom response.
>> 
>> There're few more options.
>> One option is to rethrow the WebApplicationException exception and let
>> it go to the container, it will be wrapped in a ServletException.
>> Another one is to rethrow but disable the propagation and register a
>> custom CXF OutFault interceptor. But hopefully updating your handler
>> will make a difference
>> 
>> Let me know please if you can make it work
>> Cheers, Sergey  
>> 
>> -----Original Message-----
>> From: liw [mailto:[email protected]] 
>> Sent: 18 September 2009 20:15
>> To: [email protected]
>> Subject: How to handle exception from cxf interceptors?
>> 
>> 
>> Hi,
>> 
>> We need to return custom error code and error message when exception
>> occurs
>> during REST invocation. We have created a exception mapper provider, it
>> works well for the exceptions from the application code. However, it
>> doesn't
>> work when exception occurs from the CXF code (e.g. JAXRSInInterceptor).
>> 
>> For example, if I use an invalid request url (e.g no matched path or
>> method), WebApplicationException is thrown by
>> JAXRSInInterceptor.processRequest() method.  In this case, we need to
>> return
>> a custom error code and error message in JSON format, but it doesn't
>> work
>> even though we have a  exception mapper provider created to handle
>> WebApplicationException. 
>> 
>> 
>> Is there any way to handle exceptions from cxf interceptors and return
>> response to user with something like the following? 
>> 
>> {
>>       result: {
>>           code: "E2002"
>>           message: "Invalid Request"
>>       }
>> }
>> 
>> 
>> 
>> Here is the code snippet for our exception mapper provider and it works
>> for
>> the exception from application code.
>> 
>> Code Snippet
>> ========================
>> public Response toResponse(Exception exception) {
>>              Response response = null;
>>              StdRuntimeException rootCause = null;
>>      
>>              if (exception instanceof StdRuntimeException) {
>>                      rootCause = (StdRuntimeException) exception;
>>              }
>>              else if (exception.getCause() != null &&
>> exception.getCause() instanceof
>> StdRuntimeException) {
>>                      rootCause = (StdRuntimeException)
>> exception.getCause();
>>              } 
>>              //for WebApplicationException thrown in API
>> implementation
>>              else if (exception instanceof WebApplicationException) {
>>                      response =
>> ((WebApplicationException)exception).getResponse();
>>              } 
>>              
>>              if (rootCause != null) {
>>                      String errorCode = null;
>>                      String errorMessage = null;
>>                      ErrorHandler  errorHandler = (ErrorHandler)
>> BeanFactory.getBeanInstance(AppConstants.BEAN_WSMT_ERROR_HANDLER);
>>                      try {
>>                              StdErrorMessageAdapter messageAdapter =
>> (StdErrorMessageAdapter)
>> errorHandler.handleException(rootCause);
>>                              Map errorDetails =
>> messageAdapter.getErrorDetails();
>>                              for (Map.Entry<String, List<String>> me
>> : ((Map<String, List<String>>)
>> errorDetails).entrySet()) {
>>                                      String key = me.getKey();
>>                                      if
>> (key.equals(AppConstants.PARAM_CODE)) {
>>                                              errorCode =
>> me.getValue().get(0);
>>                                      } else if
>> (key.equals(AppConstants.PARAM_MSG)) {
>>                                              errorMessage =
>> me.getValue().get(0);
>>                                      }
>>                              }
>>              }catch (Exception e) {
>>                      log.debug("Exception during handling the
>> exception. This should
>> not happen", e);
>>              }
>>              
>>                      Error error = new Error();
>>                      error.setCode(errorCode);
>>                      error.setMessage(errorMessage);
>>                      
>>                      ResponseBuilder rb =
>> Response.status(Response.Status.INTERNAL_SERVER_ERROR);
>>                      rb.type(MediaType.APPLICATION_JSON);
>>                      rb.entity(error);
>>                      response = rb.build();
>>              }
>>              return response;
>>      }
>> 
>> Thanks in advance,
>> 
>> Li
>> 
>> 
>> -- 
>> View this message in context:
>> http://www.nabble.com/How-to-handle-exception-from-cxf-interceptors--tp2
>> 5514049p25514049.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>> 
>> 
>> 
> 
> 

-- 
View this message in context: 
http://www.nabble.com/How-to-handle-exception-from-cxf-interceptors--tp25514049p25530910.html
Sent from the cxf-user mailing list archive at Nabble.com.

Reply via email to