I am trying to configure a normal (non-ajax) request error page using Omnifaces library. I am able to use the FullAjaxExceptionHandler and with ajax request error and its page as shown in the demo. When I use the same error page with normal request the error page is shown, but the values are displayed as source code (for example Date/time: #{of:formatDate(now, 'yyyy-MM-dd HH:mm:ss')} User agent: #{header['user-agent']} .. are displayed in the browser as it is).

I am using Tomcat 7, JSF 2.2 (MyFaces), Weld 2.6 (for CDI), Omnifaces 2.0 and Primefaces 5.1. The following is the relevant code.

The page:

<h:commandButton value="Throw runtime exception on normal request"      
    action="#{appbean.throwRuntimeException}"/>

<p:commandButton value="Throw runtime exception on AJAX request"        
    action="#{appbean.throwRuntimeException}"/>

The bean:

public void throwRuntimeException() {
        throw new RuntimeException("peek-a-boo");
}

faces-config:

<factory>
    <exception-handler-factory>
        org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory  
    </exception-handler-factory>
</factory>

web.xml:

<servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
</servlet-mapping>
<filter>
    <filter-name>facesExceptionFilter</filter-name>
    <filter-class>org.omnifaces.filter.FacesExceptionFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>facesExceptionFilter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<error-page>
    <exception-type>java.lang.RuntimeException</exception-type>
    <location>/WEB-INF/errorpages/error2.xhtml</location>
</error-page>
1

There are 1 answers

0
BalusC On BEST ANSWER

The <error-page><location> must match the FacesServlet mapping in order to get FacesServlet to run on the error page too during an exception on a synchronous request (which doesn't use ViewHandler#renderView(), but RequestDispatcher#forward()).

Alter the mapping accordingly:

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

Using /faces/* (and *.faces) is soo JSF 1.0/1.1. If you really need to keep /faces/* for some reason (e.g. existing webapp with already published URLs), then just use both (and migrate with 301s accordingly):

<servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>

See also: