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:vlisov...@gmail.com] >>> Sent: Tuesday, 17 November 2009 9:30 AM >>> To: users@cxf.apache.org >>> 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.