In the end I wipped up something like this, which seem to be serving the
purpose.
Now I need to figure out how to do something similar on the Soap side.
public class RestExceptionMapper implements ExceptionMapper<Exception>
{
private static Log logger = LogFactory.getLog(RestExceptionMapper.class);
private static final ResourceBundle BUNDLE =
BundleUtils.getBundle(WebApplicationExceptionMapper.class);
public Response toResponse(Exception exception)
{
logger.error("REST exception: ", exception);
if (exception instanceof WSAuthException)
{
// do not give details on auth failure
return Response.status(Response.Status.FORBIDDEN).build();
}
else if (exception instanceof WSBaseException)
{
// let custom port exception out
return
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.TEXT_PLAIN).entity(
exception.getLocalizedMessage()).build();
}
else if (exception instanceof WebApplicationException)
{
return toResponse2((WebApplicationException) exception);
}
//TODO: add one more for platform level exceptions
// the rest are server errors..
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
public Response toResponse2(WebApplicationException ex)
{
if (logger.isWarnEnabled())
{
String message = ex.getCause() == null ? ex.getMessage() :
ex.getCause().getMessage();
if (message == null)
{
if (ex.getCause() != null)
{
message = "cause is " + ex.getCause().getClass().getName();
}
else
{
message = "no cause is available";
}
}
org.apache.cxf.common.i18n.Message errorMsg =
new org.apache.cxf.common.i18n.Message("WEB_APP_EXCEPTION",
BUNDLE, message);
logger.warn(errorMsg.toString());
}
Response r = ex.getResponse();
if (r == null)
{
String message = null;
if (ex.getCause() == null)
{
message = new
org.apache.cxf.common.i18n.Message("DEFAULT_EXCEPTION_MESSAGE",
BUNDLE).toString();
}
else
{
message = ex.getCause().getMessage();
if (message == null)
{
message = ex.getCause().getClass().getName();
}
}
r =
Response.status(Response.Status.INTERNAL_SERVER_ERROR).type(MediaType.TEXT_PLAIN).entity(message).build();
}
return r;
}
}
Sergey Beryozkin-2 wrote:
>
> Hi
>
> I updated the exception handling section with few extra details, I added a
> link to a simple exception mapper used by Spring Security
> tests and also linked to a custom CXF out fault interceptor.
> So in summary here're the options for catching all the exceptions :
> - register a mapper like ExceptionMapper<Throwable>
> - register a custom out Fault Interceptor
> - register a custom Servlet filter (provided that the propogation is not
> turned off)
>
> Finally, if you'd like no exception traces reported with HTTP responses
> then just disable the propogation.
>
>> Also, I wonder
>> if you can tell why spring AOP is not working on the CXF impls? Tried to
>> debug it, but have no clear picture yet. It seems like injection hicks
>> up
>> on the wsContext member of the base class of my Impl class.
>
>>> ... 39 more
>>> Caused by: java.lang.IllegalArgumentException
>>> at
>>> sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java
>>> :37)
>>> at
>>> sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImp
>
> This exception trace looks similar. If you have a JAXWS WebServiceContext
> field then use a setter instead. Similarly for JAXRS
> MessageContext
>
> hope it helps, Sergey
>
>>
>> Hi Mustafa!
>> Yes, I need to be able to have a centrally controller backstop for all
>> exceptions coming out of my mackages, mostly .*Impl classes and custom
>> interceptors such as i.e. Auth interceptor. Soap already kind of does it
>> for
>> me by wrapping it into a generic Fault (I actually wanted MyException
>> class
>> instead, but I can live with Fault for unexpected errors on the Soap
>> side.
>> The jaxrs REST side behaves differently by exposing full stack traces,
>> which
>> is what I don't want clients to see - there is log file for that
>> purpose..
>> The mapper sounds like what I could use, do you have an example how to
>> intercept or map a Exception and rethrow MyException instead? Also, I
>> wonder
>> if you can tell why spring AOP is not working on the CXF impls? Tried to
>> debug it, but have no clear picture yet. It seems like injection hicks
>> up
>> on the wsContext member of the base class of my Impl class.
>>
>>
>>
>> Mustafa Sezgin-2 wrote:
>>>
>>> From my understanding you basically want a centralised place to handle
>>> exceptions and a way to control what is returned to the client? We use
>>> an
>>> exception mapper which receives all possible exceptions and you can then
>>> return the desired response object based on the exception. We have a
>>> many
>>> to one mapping between exceptions and the status codes we return in XML
>>> format and are able to handle all exceptions ensuring that not undesired
>>> responses get sent back to the client.
>>>
>>> Have a look at
>>> http://cwiki.apache.org/CXF20DOC/jax-rs.html#JAX-RS-Exceptionhandling
>>>
>>> -----Original Message-----
>>> From: vickatvuuch [mailto:[email protected]]
>>> Sent: Tuesday, 17 November 2009 9:30 AM
>>> To: [email protected]
>>> Subject: CXF jaxrs REST exception stack trace propagated to REST client,
>>> can exception be wrapped up or filtered out or AOP intercepted?
>>>
>>>
>>> Hi All,
>>>
>>> Is there a way to Not propagate unchecked exception stack traces back to
>>> the
>>> client?
>>>
>>> Use case: I have a port, that expects certain parameters, if one of them
>>> is
>>> null
>>> it may throw unchecked IllegalArgumentException, which could be
>>> rectified
>>> if
>>> it was
>>> all under my control.
>>>
>>> Imagine that other team members adding new ports and not wrapping it up
>>> completely.
>>> What I wanted was to have a way to control what goes out to the client
>>> hopefully in one place.
>>>
>>> For instance I have defined WSBaseException from which all other WS
>>> layer
>>> exceptions
>>> should be derived and thrown out of the WS layer (annotated with
>>> WebFault).
>>>
>>> First thing I did, I tried try AOP "after-throwing" pointcut, which is
>>> where
>>> I was hoping to intercept all outgoing exceptions and wrap them up in
>>> the
>>> WSBaseException for anything
>>> that would come out unless it was already WSBaseException, but that
>>> didn't
>>> work, still debugging why it fails, btw AOP config and exception is
>>> below:
>>> But my question is mostly about how to do this without
>>> extra AOP, does CXF has a way of dealing with this situation already,
>>> may
>>> be
>>> I'm missing something?
>>> Thanks,
>>> -Vitaly
>>>
>>> <bean id="wsExceptionInterceptorAspect"
>>> class="com.foo.webservices.v1.WSExceptionTranslator"/>
>>>
>>> <aop:config>
>>> <aop:pointcut id="wsServiceOperation"
>>> expression="execution(*
>>> com.foo.webservices.v1.ports.auth.MyServiceImpl*.(..))"/>
>>>
>>> <aop:aspect id="wsAfterThrowing" ref="wsExceptionInterceptorAspect">
>>> <aop:after-throwing pointcut-ref="wsServiceOperation"
>>> throwing="exception" method="afterThrowing"/>
>>> </aop:aspect>
>>> </aop:config>
>>>
>>> The above blows up on server startup, when it is loading the Imlp on
>>> which
>>> I
>>> have a pointcut:
>>>
>>> jaxws.EndpointImpl---1853031827,org.apache.cxf.jaxrs.spring.JAXRSServerFac
>>> toryBeanDefinitionParser$SpringJAXRSServerFact
>>> oryBean--1917449182,org.apache.cxf.jaxws.EndpointImpl--1050608923,org.apac
>>> he.cxf.jaxws.EndpointImpl--880314741,wsExcepti
>>> onInterceptorAspect,org.springframework.aop.config.internalAutoProxyCreato
>>> r,wsServiceOperation,org.springframework.aop.a
>>> spectj.AspectJPointcutAdvisor#0]; root of factory hierarchy
>>> - Context initialization failed
>>> org.springframework.beans.factory.BeanCreationException: Error creating
>>> bean
>>> with name 'org.apache.cxf.jaxws.EndpointImp
>>> l---1687321673': Invocation of init method failed; nested exception is
>>> javax.xml.ws.WebServiceException: Creation of End
>>> point failed
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.initializeBean(AbstractAutowireC
>>> apableBeanFactory.java:1338)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.doCreateBean(AbstractAutowireCap
>>> ableBeanFactory.java:473)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry$1.run(AbstractAutowireCapableBea
>>> nFactory.java:409)
>>> at java.security.AccessController.doPrivileged(Native Method)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.createBean(AbstractAutowireCapab
>>> leBeanFactory.java:380)
>>> at
>>> org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(
>>> AbstractBeanFactory.java:264)
>>> at
>>> org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.get
>>> Singleton(DefaultSingletonBeanRegis
>>> try.java:222)
>>> at
>>> org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(Ab
>>> stractBeanFactory.java:261)
>>> at
>>> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(Abst
>>> ractBeanFactory.java:185)
>>> at
>>> org.springframework.beans.factory.support.AbstractBeanFactory.getBean(Abst
>>> ractBeanFactory.java:164)
>>> at
>>> org.springframework.beans.factory.support.DefaultListableBeanFactory.preIn
>>> stantiateSingletons(DefaultListable
>>> BeanFactory.java:429)
>>> at
>>> org.springframework.context.support.AbstractApplicationContext.finishBeanF
>>> actoryInitialization(AbstractApplic
>>> ationContext.java:728)
>>> at
>>> org.springframework.context.support.AbstractApplicationContext.refresh(Abs
>>> tractApplicationContext.java:380)
>>> at
>>> org.springframework.web.context.ContextLoader.createWebApplicationContext(
>>> ContextLoader.java:255)
>>> at
>>> org.springframework.web.context.ContextLoader.initWebApplicationContext(Co
>>> ntextLoader.java:199)
>>> at
>>> org.springframework.web.context.ContextLoaderListener.contextInitialized(C
>>> ontextLoaderListener.java:45)
>>> at
>>> org.apache.catalina.core.StandardContext.listenerStart(StandardContext.jav
>>> a:3934)
>>> at
>>> org.apache.catalina.core.StandardContext.start(StandardContext.java:4429)
>>> at
>>> org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java
>>> :791)
>>> at
>>> org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
>>> at
>>> org.apache.catalina.core.StandardHost.addChild(StandardHost.java:526)
>>> at
>>> org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:850)
>>> at
>>> org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:724)
>>> at
>>> org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:493)
>>> at
>>> org.apache.catalina.startup.HostConfig.start(HostConfig.java:1206)
>>> at
>>> org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:314)
>>> at
>>> org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupp
>>> ort.java:119)
>>> at
>>> org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
>>> at
>>> org.apache.catalina.core.StandardHost.start(StandardHost.java:722)
>>> at
>>> org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
>>> at
>>> org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
>>> at
>>> org.apache.catalina.core.StandardService.start(StandardService.java:516)
>>> at
>>> org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
>>> at org.apache.catalina.startup.Catalina.start(Catalina.java:583)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
>>> 39)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorIm
>>> pl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
>>> at
>>> org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
>>> Caused by: javax.xml.ws.WebServiceException: Creation of Endpoint failed
>>> at
>>> org.apache.cxf.jaxws.JaxWsServerFactoryBean.init(JaxWsServerFactoryBean.ja
>>> va:181)
>>> at
>>> org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.
>>> java:168)
>>> at
>>> org.apache.cxf.jaxws.EndpointImpl.getServer(EndpointImpl.java:346)
>>> at
>>> org.apache.cxf.jaxws.EndpointImpl.doPublish(EndpointImpl.java:259)
>>> at
>>> org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:209)
>>> at
>>> org.apache.cxf.jaxws.EndpointImpl.publish(EndpointImpl.java:404)
>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>> at
>>> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
>>> 39)
>>> at
>>> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorIm
>>> pl.java:25)
>>> at java.lang.reflect.Method.invoke(Method.java:585)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.invokeCustomInitMethod(AbstractA
>>> utowireCapableBeanFactory.java:1414)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.invokeInitMethods(AbstractAutowi
>>> reCapableBeanFactory.java:1375)
>>> at
>>> org.springframework.beans.factory.support.AbstractAutowireCapableBeanFacto
>>> ry.initializeBean(AbstractAutowireC
>>> apableBeanFactory.java:1335)
>>> ... 39 more
>>> Caused by: java.lang.IllegalArgumentException
>>> at
>>> sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java
>>> :37)
>>> at
>>> sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImp
>>> l.java:57)
>>> at java.lang.reflect.Field.set(Field.java:656)
>>> at
>>> org.apache.cxf.common.injection.ResourceInjector.injectField(ResourceInjec
>>> tor.java:283)
>>> at
>>> org.apache.cxf.common.injection.ResourceInjector.visitField(ResourceInject
>>> or.java:167)
>>> at
>>> org.apache.cxf.common.annotation.AnnotationProcessor.processFields(Annotat
>>> ionProcessor.java:101)
>>> at
>>> org.apache.cxf.common.annotation.AnnotationProcessor.processFields(Annotat
>>> ionProcessor.java:95)
>>> at
>>> org.apache.cxf.common.annotation.AnnotationProcessor.accept(AnnotationProc
>>> essor.java:69)
>>> at
>>> org.apache.cxf.common.injection.ResourceInjector.inject(ResourceInjector.j
>>> ava:81)
>>> at
>>> org.apache.cxf.jaxws.JaxWsServerFactoryBean.injectResources(JaxWsServerFac
>>> toryBean.java:221)
>>> at
>>> org.apache.cxf.jaxws.JaxWsServerFactoryBean.init(JaxWsServerFactoryBean.ja
>>> va:175)
>>> ... 51 more
>>> Nov 16, 2009 5:23:23 PM org.apache.catalina.core.StandardContext start
>>> --
>>> View this message in context:
>>> http://old.nabble.com/CXF-jaxrs-REST-exception-stack-trace-propagated-to-R
>>> EST-client%2C-can-exception-be-wrapped-up-or-filtered-out-or-AOP-intercept
>>> ed--tp26379915p26379915.html
>>> Sent from the cxf-user mailing list archive at Nabble.com.
>>>
>>>
>>>
>>
>> --
>> View this message in context:
>> http://old.nabble.com/CXF-jaxrs-REST-exception-stack-trace-propagated-to-REST-client%2C-can-exception-be-wrapped-up-or-filtered-out-or-AOP-intercepted--tp26379915p26384165.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>>
>
>
>
--
View this message in context:
http://old.nabble.com/CXF-jaxrs-REST-exception-stack-trace-propagated-to-REST-client%2C-can-exception-be-wrapped-up-or-filtered-out-or-AOP-intercepted--tp26379915p26396467.html
Sent from the cxf-user mailing list archive at Nabble.com.