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--tp25514049p25515718.html
Sent from the cxf-user mailing list archive at Nabble.com.