org.omnifaces.exceptionhandler
Class FullAjaxExceptionHandler

java.lang.Object
  extended by javax.faces.context.ExceptionHandler
      extended by javax.faces.context.ExceptionHandlerWrapper
          extended by org.omnifaces.exceptionhandler.FullAjaxExceptionHandler
All Implemented Interfaces:
java.util.EventListener, javax.faces.event.FacesListener, javax.faces.event.SystemEventListener, javax.faces.FacesWrapper<javax.faces.context.ExceptionHandler>

public class FullAjaxExceptionHandler
extends javax.faces.context.ExceptionHandlerWrapper

This exception handler enables you to show the full error page in its entirety to the enduser in case of exceptions during ajax requests. Refer the documentation of FullAjaxExceptionHandlerFactory how to setup it.

This exception handler will parse the web.xml and web-fragment.xml files to find the error page locations of the HTTP error code 500 and all declared specific exception types. Those locations need to point to Facelets files. The location of the HTTP error code 500 or the exception type java.lang.Throwable is required in order to get the full ajax exception handler to work, because there's then at least a fall back error page whenever there's no match with any of the declared specific exceptions. So, you must at least have either

 <error-page>
   <error-code>500</error-code>
   <location>/errors/500.xhtml</location>
 </error-page>
 

or

 <error-page>
   <exception-type>java.lang.Throwable</exception-type>
   <location>/errors/500.xhtml</location>
 </error-page>
 

Both can also, only the java.lang.Throwable one will always get precedence over the 500 one, as per the Servlet API specification, so the 500 one would be basically superfluous.

The exception detail is available in the request scope by the standard servlet error request attributes like as in a normal synchronous error page response. You could for example show them in the error page as follows:

 <ul>
   <li>Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')}</li>
   <li>User agent: #{header['user-agent']}</li>
   <li>User IP: #{request.remoteAddr}</li>
   <li>Request URI: #{requestScope['javax.servlet.error.request_uri']}</li>
   <li>Ajax request: #{facesContext.partialViewContext.ajaxRequest ? 'Yes' : 'No'}</li>
   <li>Status code: #{requestScope['javax.servlet.error.status_code']}</li>
   <li>Exception type: #{requestScope['javax.servlet.error.exception_type']}</li>
   <li>Exception message: #{requestScope['javax.servlet.error.message']}</li>
   <li>Stack trace:
     <pre>#{of:printStackTrace(requestScope['javax.servlet.error.exception'])}</pre>
   </li>
 </ul>
 

Author:
Bauke Scholtz
See Also:
FullAjaxExceptionHandlerFactory

Constructor Summary
FullAjaxExceptionHandler(javax.faces.context.ExceptionHandler wrapped)
          Construct a new ajax exception handler around the given wrapped exception handler.
 
Method Summary
 javax.faces.context.ExceptionHandler getWrapped()
           
 void handle()
          Handle the ajax exception as follows, only and only if the current request is an ajax request and there is at least one unhandled exception: If the exception is an instance of FacesException, then unwrap its root cause as long as it is not an instance of FacesException.
 
Methods inherited from class javax.faces.context.ExceptionHandlerWrapper
getHandledExceptionQueuedEvent, getHandledExceptionQueuedEvents, getRootCause, getUnhandledExceptionQueuedEvents, isListenerForSource, processEvent
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

FullAjaxExceptionHandler

public FullAjaxExceptionHandler(javax.faces.context.ExceptionHandler wrapped)
Construct a new ajax exception handler around the given wrapped exception handler.

Parameters:
wrapped - The wrapped exception handler.
Method Detail

handle

public void handle()
            throws javax.faces.FacesException
Handle the ajax exception as follows, only and only if the current request is an ajax request and there is at least one unhandled exception:
  • If the exception is an instance of FacesException, then unwrap its root cause as long as it is not an instance of FacesException.
  • Find the error page location as per Servlet specification 10.9.2:
    • Make a first pass through all specific exception types. If an exact match is found, use its location.
    • Else make a second pass through all specific exception types in the order as they are declared in web.xml. If the current exception is an instance of it, then use its location.
    • Else use the default error page location, which can be either the HTTP 500 or java.lang.Throwable one.
  • Set the standard servlet error request attributes.
  • Force JSF to render the full error page in its entirety.
Any remaining unhandled exceptions will be swallowed. Only the first one is relevant.

Overrides:
handle in class javax.faces.context.ExceptionHandlerWrapper
Throws:
javax.faces.FacesException

getWrapped

public javax.faces.context.ExceptionHandler getWrapped()
Specified by:
getWrapped in interface javax.faces.FacesWrapper<javax.faces.context.ExceptionHandler>
Overrides:
getWrapped in class javax.faces.context.ExceptionHandlerWrapper