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.