Adding global exception handling using JSF 2.x ExceptionHandler

This a great feature of JSF 2.x: A generic API to manipulate application exception in a global manner. In order to implement this you must implement (extend) two different classes:

ExceptionHandlerWrapper – Provides a simple implementation of ExceptionHandler that can be subclassed by developers wishing to provide specialized behavior to an existing ExceptionHandler instance. The default implementation of all methods is to call through to the wrapped ExceptionHandler instance.

ExceptionHandlerFactory – A factory object that creates (if needed) and returns a new ExceptionHandler instance.

On Duke’s Forest this is the implementation:

package com.forest.exception;

public class CustomExceptionHandlerFactory extends ExceptionHandlerFactory {
   private ExceptionHandlerFactory parent;

   // this injection handles jsf
   public CustomExceptionHandlerFactory(ExceptionHandlerFactory parent) {
    this.parent = parent;

    public ExceptionHandler getExceptionHandler() {

        ExceptionHandler handler = new            CustomExceptionHandler(parent.getExceptionHandler());

        return handler;


package com.forest.exception;

public class CustomExceptionHandler extends ExceptionHandlerWrapper {
    private static final Logger log = Logger.getLogger(CustomExceptionHandler.class.getCanonicalName());
    private ExceptionHandler wrapped;

    CustomExceptionHandler(ExceptionHandler exception) {
        this.wrapped = exception;

    public ExceptionHandler getWrapped() {
        return wrapped;

    public void handle() throws FacesException {

        final Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator();
        while (i.hasNext()) {
            ExceptionQueuedEvent event =;
            ExceptionQueuedEventContext context =
                    (ExceptionQueuedEventContext) event.getSource();

            // get the exception from context
            Throwable t = context.getException();

            final FacesContext fc = FacesContext.getCurrentInstance();
            final Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
            final NavigationHandler nav = fc.getApplication().getNavigationHandler();

            //here you do what ever you want with exception
            try {

                //log error ?
                log.log(Level.SEVERE, "Critical Exception!", t);

                //redirect error page
                requestMap.put("exceptionMessage", t.getMessage());
                nav.handleNavigation(fc, null, "/error");

                // remove the comment below if you want to report the error in a jsf error message

            } finally {
                //remove it from queue
        //parent hanle

And add the following lines to your faces-config.xml:


In the try-finally block you can cast the Throwable to any specific exception and do  any special treatment that you want. For example: ViewExpiredException can be redirected to a “Session Expired” page and on the other hand, NullPointerException can use the common generic page just saying that “An unexpected situation occurred, please try again later.”

In line 40 I’m redirecting to a common error page (/error) which can read error information from the request map.

Please note that when dealing with exceptions and web development, you must ensure that you are not sharing any unwanted sensitive information when returning the error to the web page.

To see the complete running example please check The Java EE 6 Tutorial and check Duke’s Forest case study.


12 thoughts on “Adding global exception handling using JSF 2.x ExceptionHandler

  1. Hi, great presentation.
    Could you please publish your faces-config.xml (navigation rule for error page)

    When I use redirect the request map value are null. Without redirect, the user stays at the initial error page.


  2. Hi and sorry for the long long delay to answer – I was completely out due to some health issues.
    So, there is no navigation rule, the redirect is done only by the class at line 40.

    //redirect error page
    requestMap.put(“exceptionMessage”, t.getMessage());
    nav.handleNavigation(fc, null, “/error”);

    What you probably need to do is to populate the requestMap with the data you want to keep from the previous request, since this redirect is almost like a new request, any data you have will not be automatically carried to this redirect.


  3. apanag said “Could you please publish your faces-config.xml (navigation rule for error page)”
    so could you lease reply ?
    thx a lot

  4. <?xml version='1.0' encoding='UTF-8'?>
    <!-- =========== FULL CONFIGURATION FILE ================================== -->
    <faces-config version="2.0"
  5. It does not work with ajax requests. You should use:

    context.setViewRoot(context.getApplication().getViewHandler().createView(context, viewId));

  6. When I do this I’m getting the following exception. Can you please help me with this?

    java.lang.IllegalStateException: Could not find backup for factory javax.faces.application.ApplicationFactory.
    at javax.faces.FactoryFinder$FactoryManager.getFactory(
    at javax.faces.FactoryFinder.getFactory(
    at com.sun.faces.config.InitFacesContext.getApplication(
    at com.sun.faces.config.ConfigureListener.contextDestroyed(
    at org.apache.catalina.core.StandardContext.listenerStop(
    at org.apache.catalina.core.StandardContext.stopInternal(
    at org.apache.catalina.util.LifecycleBase.stop(
    at org.apache.catalina.util.LifecycleBase.start(
    at org.apache.catalina.core.ContainerBase$
    at org.apache.catalina.core.ContainerBase$
    at java.util.concurrent.ThreadPoolExecutor.runWorker(
    at java.util.concurrent.ThreadPoolExecutor$

  7. I’ve some additional tip:
    1. if your JSF application is in response phase (phase 6), you have not to remove getUnhandledExceptionQueuedEvents.iterator(). You’ve to use web.xml configuration to handle. E.g.


    2. if it’s in invoke application phase (phase 5), you’ve to remove getUnhandledExceptionQueuedEvents.iterator().
    These’re the updated codes:

    requestMap.put(“exceptionMessage”, t.getMessage());
    if (!fc.getRenderResponse()) {
    nav.handleNavigation(fc, null, “/errors/unauthorizedException.xhtml”);
    // remove the comment below if you want to report the error in a jsf error message
    } finally {
    //remove it from queue if not in render response mode
    if (!fc.getRenderResponse()) {

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s