Hi Henrik,

Yes, give it a try please.
Happy Christmas to you too :-)
Sergey 

-----Original Message-----
From: Henrik Martin [mailto:[email protected]] 
Sent: 23 December 2009 18:54
To: [email protected]
Subject: Re: Need some more help on error handling

Thanks Sergey. I think I'll try to subclass the CXFServlet + the
controller and override the necessary methods. Kudos to you and the rest
of the CXF team for excellent support! Happy holidays to y'all. 

/Henrik

On Wed, 2009-12-23 at 13:16 +0000, Sergey Beryozkin wrote:
> Hi
> 
> > Greetings. I'm thoroughly confused about the gazillion ways of
handling
> > errors in CXF/JAX-RS. I've read whatever documentation I've found on
the
> > wiki, and have followed the many posts to the mailing list on this
> > subject, and I still can't figure out how to cover all corner cases
> > without hacking the CXF source code (a situation I don't want to get
> > into).
> 
> Ok :-).
> As far as JAX-RS itself is concerned, there are 3 ways to deal with
errors (marked as JAXRS1, etc).
> 
> JAXRS1. Return a JAXRS Response directly from a resource method, with
this Response containing the appropriate status code
> 
> JAXRS2. Create as many ExceptionMappers as needed which will capture
exceptions and convert them into appropriate Responses. One 
> might have a single mapper capturing all the exceptions or a number of
mappers capturing seperate exceptions...CXF JAXRS ships a 
> default WebApplicationExceptionMapper but one can register a custom
WebApplicationExceptionMapper if the responses produced by the 
> default mapper are not satisfactory in some specific cases.
> 
> JAXRS3. Have Servlet Filter capturing ServletExceptions - all the
exceptions which have been not mapped by the mappers earlier on 
> will be visible to Servlet Filter.
> 
> These options should give you a 100% coverage.
> Next, CXF JAX-RS and CXF offers few more options (marked as CXF1,
etc).
> 
> CXF1. As noted in JAXRS2, one can override responses produced by
default mapper by registering a custom 
> WebApplicationExceptionMapper but the CXF JAXRS specifc option is to
register a ResponseHandler filter instead and override the 
> Response there
> 
> CXF2. One can configure CXF JAXRS to block the propagation of the
unmapped execptions to the Servlet filter in which case CXF XML 
> Binding (which CXF JAX-RS depends upon) will wrap the exception in its
xml-specific format
> 
> CXF3. One can register CXF fault interceptors and handle all the
exceptions in these interceptors.
> 
> That is probably it, does it clarify things a bit ?
> 
> >
> > I need to capture 100% of all possible errors that can ever happen
> > inside CXF, the web container (Tomcat 6.X), and any possible CXF
> > application running in the container (we ONLY use REST based
services
> > using CXF), and stream the errors/exceptions out as XML (we use
XStream
> > for that). That's the requirement.
> >
> > Here's what I've done:
> >
> > 1) I wrote a piece of code that implements the ResponseHandler
> > interface. I do quite a bit of analysis inside that code, and return
a
> > custom response called an ErrorResponse. This eventually gets
streamed
> > out to XML. This ResponseHandler is configured as a provider with
the
> > <jaxrs:providers> mechanism in our Spring config file. It seems to
cover
> > the cases where the error condition is wrapped inside a Response
object.
> 
> Yes, it is option CXF1 but also see option JAXRS2. I'm not sure when
this code even executes for you given that you
> say in 2) below that you capture all the exceptions with exception
mappers.
> 
> >
> > 2) I implemented a bunch of ExceptionMapper classes for the most
common
> > exceptions, as well as a "catch-all" for other exceptions. This
seems to
> > cover the cases where a service is throwing an exception. My mappers
> > convert the exception to XML and stuffs that in a Response object.
The
> > mappers are also configured using the <jaxrs:providers> mechanism.
> 
> OK
> 
> >
> > 3) I wrote an a piece of code that extends the
> > AbstractOutDatabindingInterceptor class (based on the CXF example
that
> > Sergey posted a while back). This is configured using the following
> > mechanism:
> >
> > <cxf:bus>
> >  <cxf:outFaultInterceptors>
> >    <ref bean="XMLOutFault.Interceptor"/>
> >  </cxf:outFaultInterceptors>
> > </cxf:bus>
> 
> You probably do not need it if you already do 1) and 2) unless you
also do JAXWS. If both JAXWS & JAXRS are involved then relying on 
> fault interceptors can be quite an attractive option...
> 
> >
> > 4) I wrote a Servlet Filter (implementing the javax.servlet.Filter
> > interface), that catches any exception and streams it out as XML.
The
> > problem is that nothing downstream seems to throw any exceptions, so
the
> > doFilter() method always returns normally.
> 
> This is expected because in 2) you've captured all the exceptions.
Only those exceptions which have not been mapped will be 
> propagated
> 
> >
> > I need to know what I have to do to cover 100% of all possible error
> > cases, and stream the error out using our custom XStream transcode
back
> > to the client. Some code samples or fairly detailed info about how
to
> > write the code, and how to wire it up would be fantastic. One of the
> > corner cases NOT covered by any of the above mentioned mechanisms is
> > when I specify a URL that is not mapped by CXF. In this case, the
> > org.apache.cxf.transport.servlet.ServletController's invoke() method
> > will call generateNotFound(), which sets the HTTP status code to
404,
> > and writes an error message directly to the HttpServletResponse. How
can
> > I override this?
> 
> Perhaps you can extend CXFServlet and override its protected
createServletController and then override generateNotFound() on your 
> custom controller ?
> 
> Another, possibly a more awkward workaround is to use your custom
ServletFilter and pass along an HttpResponse filter ? Please see 
> HttpServletResponseFilter and ServletOutputStreamFilter in the CXF
JAXRS source for some basic example...Ex, given
> 
> protected void generateNotFound(HttpServletRequest request,
HttpServletResponse res) throws IOException {
> 
> res.setStatus(404);
> 
> res.setContentType("text/html");
> 
> res.getWriter().write("<html><body>No service was
found.</body></html>");
> 
> }
> 
> you can override in your HttpResponse filter  setContentType() and
setStatus() and if you get "text/html" and "404" (CXF JAXRS can 
> also reply with 404 but it won't set text/html) then it is that edge
case you're dealing with and if it is the case then in 
> getWriter() your return a StringWriter buffer instead to block the
default response....
> 
> >
> > I don't want ANY component other than my code, writing ANYTHING to
the
> > servlet's OutputStream in case something goes wrong. I absolutely
have
> > to control 100% of all error handling. Any tips, tricks, and
pointers to
> > examples are greatly appreciated. Thanks much,
> 
> At the moment I think that given the above, you can get a 100%
coverage...
> 
> thanks, Sergey
> 
> >
> > /Henrik
> >
> > 
> 

Reply via email to