Possibilities for exception handling in PrimeFaces

PrimeFaces provides powerful exception handling for AJAX and non-AJAX requests out of the box. The mapping between error pages and exception types is configured via the error-page ability in web.xml. Exceptions for AJAX requests can also be configured via the special p:ajaxExceptionHandler tag in order for them to be shown on the same page where they occurred. An implicit object, pfExceptionHandler, provides useful information about exception details.

In this recipe, we will give helpful tips about configuration details and demonstrate PrimeFaces' exception handling for AJAX and non-AJAX requests.

Getting ready

In order to be able use the exception handling, a special EL resolver and a factory class for 'ExceptionHandler of PrimeFaces should be registered in faces-config.xml:

<application>
  <el-resolver>
    org.primefaces.application.
      exceptionhandler.PrimeExceptionHandlerELResolver
  </el-resolver>
</application>

<factory>
  <exception-handler-factory>
    org.primefaces.application.
      exceptionhandler.PrimeExceptionHandlerFactory
  </exception-handler-factory>
</factory>

PrimeFaces parses the web.xml file on application startup to figure out an appropriate page to redirect to when an exception of a certain type occurs. The web.xml file of the showcase contains three error-page entries:

<error-page>
  <exception-type>
    java.lang.Throwable
  </exception-type>
  <location>
    /views/chapter11/errors/throwable.jsf
  </location>
</error-page>
<error-page>
  <exception-type>
   java.lang.IllegalStateException
  </exception-type>
  <location>
    /views/chapter11/errors/illegalState.jsf
  </location>
</error-page>
<error-page>
  <exception-type>
    javax.faces.application.ViewExpiredException
  </exception-type>
  <location>
    /views/chapter11/errors/viewExpired.jsf
  </location>
</error-page>

There are two pages for the special exception types, IllegalStateException and ViewExpiredException, and one generic page for all other kind of exceptions.

In addition to this, you can set the javax.faces.FACELETS_BUFFER_SIZE context parameter in web.xml to support exception handling in the RENDER_RESPONSE phase. Otherwise, you will probably see javax.servlet.ServletException: Response already committed. This is shown in the following code:

<context-param>
  <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
  <param-value>65535</param-value>
</context-param>

How to do it…

We will develop three AJAX-ified p:commandButton components and three others to send non-AJAX requests. All buttons invoke actions, which throw different exceptions. We will also have a p:ajaxExceptionHandler tag for ViewExpiredException. This kind of exception mostly occurs when the session expires. In this case, we would like to update and show a dialog with the exception details and a Reload button. This is shown in the following code:

<h3 style="margin-top:0">AJAX requests</h3>

<p:commandButton value="Throw NullPointerException"
  action="#{exceptionHandlerBean.throwNullPointerException}"/>
<p:commandButton value="Throw IllegalStateException"
  action="#{exceptionHandlerBean.throwIllegalStateException}"/>
<p:commandButton value="Throw ViewExpiredException"
  action="#{exceptionHandlerBean.throwViewExpiredException}"/>

<h3 style="margin-top:20px">Non-AJAX requests</h3>

<p:commandButton ajax="false" value="Throw NullPointerException"
  action="#{exceptionHandlerBean.throwNullPointerException}"/>
<p:commandButton ajax="false" value="Throw IllegalStateException"
  action="#{exceptionHandlerBean.throwIllegalStateException}"/>
<p:commandButton ajax="false" value="Throw ViewExpiredException"
  action="#{exceptionHandlerBean.throwViewExpiredException}"/>

<p:ajaxExceptionHandler update="expDialog"
  type="javax.faces.application.ViewExpiredException"
  onexception="PF('exceptionDialog').show();"/>

<p:dialog id="expDialog" header="#{pfExceptionHandler.type} occured!"
  widgetVar="exceptionDialog" height="500px">
  Message: #{pfExceptionHandler.message}
  <br/>
  Timestamp: #{pfExceptionHandler.formattedTimestamp}
  <br/>
  StackTrace:
  <h:outputText value="#{pfExceptionHandler.formattedStackTrace}"
    escape="false"/>

  <p:button value="Reload the application!"
    style="margin:20px 5px 20px 5px"
    onclick="document.location.href = document.location.href;"/>
</p:dialog>

The dialog is quite useful if you do not want to create a separate error page, as shown in the following screenshot:

How to do it…

The separate error pages, viewExpired.jsf, illegalState.jsf, and throwable.jsf, have some common information about the exception thrown. For instance, the throwable.jsf page looks like this:

<h3 style="margin-top:0">
  <strong>Oops, an unexpected error occured</strong>
</h3>

Message: #{pfExceptionHandler.message}
<br/>
Timestamp: #{pfExceptionHandler.formattedTimestamp}
<br/>
StackTrace:
<h:outputText value="#{pfExceptionHandler.formattedStackTrace}"
  escape="false"/>

The following screenshot shows the exact output of this page:

How to do it…

How it works…

The viewExpired.jsf and illegalState.jsf error pages are configured for exceptions of the types ViewExpiredException and IllegalStateException, respectively. Any other exceptions are caught by the java.lang.Throwable type and will be redirected to the throwable.jsf page.

The p:ajaxExceptionHandler exception handler component provides a way to update other components on the same page and execute the onexception callback on the client side after that. Be aware that the p:ajaxExceptionHandler component is only valid for AJAX requests. It does not have any effect on non-AJAX requests. In the example, ViewExpiredException is shown on a separate page for non-AJAX requests.

Tip

Place p:ajaxExceptionHandler in your Facelets master template so that it will be included in every page.

Information about the exception is provided via the keyword, pfExceptionHandler, and can be accessed on a page by EL expressions such as #{pfExceptionHandler.message}. All exposed properties are listed here:

Property

Description

exception

This is an exception instance

type

This is the type of the exception

message

This is the exception message

stackTrace

This is an array of java.lang.StackTraceElement instances

formattedStackTrace

This sets stack trace as a presentable string

timestamp

This sets a timestamp as a date

formattedTimestamp

This sets a timestamp as a presentable string

PrimeFaces Cookbook Showcase application

This recipe is available in the demo web application on GitHub (https://github.com/ova2/primefaces-cookbook/tree/second-edition). Clone the project if you have not done it yet, explore the project structure, and build and deploy the WAR file on application servers compatible with Servlet 3.x, such as JBoss WildFly and Apache TomEE.

The showcase for the recipe is available at http://localhost:8080/pf-cookbook/views/chapter11/exceptionHandling.jsf.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.216.175