4

I am trying to navigate to error page if an exception occurred. For that I have defined:

<error-page>
    <error-code>500</error-code>
    <location>/error.jspx</location>
</error-page> 

in the web.xml. Also I have tried to do this by Servlet:

<servlet>
    <servlet-name>ErrorHandler</servlet-name>
    <servlet-class>web.servlet.ErrorHandler</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ErrorHandler</servlet-name>
    <url-pattern>/errorhandler</url-pattern>
</servlet-mapping>
<error-page>
    <error-code>500</error-code>
    <location>/errorhandler</location>
</error-page>

But neither it is navigating to the error.jspx nor the ErrorHandler Servlet get called.

To test the error handling I have tried to throw new Exception("Test"); from both of the constructor of managed bean and also from actionListener. But it is printing the exception in console but the redirection is not happening.

I have also tried with: <exception-type>java.lang.Exception</exception-type> instead of <error-code>500</error-code>, but no luck. How can I invoke the Servlet or navigate to the page whenever any exception is occurred from anywhere like the constructor or some action/actionListener?

Brian Robbins
  • 290
  • 3
  • 17
Tapas Bose
  • 28,796
  • 74
  • 215
  • 331

1 Answers1

0

I do not know if this will serve you. I have a handler for any error defined as follows.

In "faces-config.xml"

 <factory> 
     <exception-handler-factory> 
        com.mypackage.global.DatExceptionHandlerFactory 
     </exception-handler-factory>
  </factory> 

And two classes

import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;

public class DatExceptionHandlerFactory extends ExceptionHandlerFactory {

      private ExceptionHandlerFactory parent;

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

      //create your own ExceptionHandler
      @Override
      public ExceptionHandler getExceptionHandler() {
        ExceptionHandler result =
            new DatExceptionHandler(parent.getExceptionHandler());
        return result;
      }
    }

Second class

import java.util.Iterator;
import javax.faces.FacesException;
import javax.faces.application.NavigationHandler;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


public class DatExceptionHandler extends ExceptionHandlerWrapper {

      private static Log log = LogFactory.getLog(DatExceptionHandler.class);
      private ExceptionHandler wrapped;
      public  String error = "n";


      public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    public DatExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
      }

      @Override
      public ExceptionHandler getWrapped() {
        return wrapped;
      }

      @Override
      public void handle() throws FacesException {
        Iterator iterator = getUnhandledExceptionQueuedEvents().iterator();

        while (iterator.hasNext()) {
          ExceptionQueuedEvent event = (ExceptionQueuedEvent) iterator.next();
          ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)event.getSource();

          Throwable throwable = context.getException();

          FacesContext fc = FacesContext.getCurrentInstance();

          try {
              Flash flash = fc.getExternalContext().getFlash();

              // Put the exception in the flash scope to be displayed in the error 
              // page if necessary ...
              flash.put("errorDetails", throwable.getMessage());

              System.out.println("the error is put in the flash: " + throwable.getMessage());

              NavigationHandler navigationHandler = fc.getApplication().getNavigationHandler();

              navigationHandler.handleNavigation(fc, null, "components/errorHandler.xhtml?faces-redirect=true");

              fc.renderResponse();
          } finally {
              iterator.remove();
          }
        }

        // Let the parent handle the rest
        getWrapped().handle();
      }
    }

And errorHandler.xhtml to show error

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html">

<h:head>
  <link type="text/css" rel="stylesheet" href="#request.contextPath}/css/default.css" /> 
  <title>#{bundle['guessNumber.error_page.title']}</title>
</h:head>

<h:body>
    <div class="highlighted errorMessage">
        <h:outputText escape="false" 
                      value="#{bundle['guessNumber.error_page.content']}"/>
    </div>
    <br/><br/>
    <div class="errorDetails">
        Error details: <br/>
        #{flash.keep.errorDetails}
    </div>
</h:body>
</html>
Rafa Hernández
  • 468
  • 7
  • 19