3 Replies Latest reply on Dec 26, 2007 3:55 PM by Pete Muir

    Newbie Problem with Exception handling and pages.xml

    Steven Headley Newbie

      I am new with seam and require a little bit of guidance. I am trying to handle application wide exceptions through the use of pages.xml and the <exception class> tags. If I forceably thow an exception in my application for testing purpose, with the following tag in my pages.xml:


      <end-conversation/>
      <redirect view-id="/views/admin/error.xhtml">
      Database access failed



      I get the following view which is incorrect:

      500 Internal Server Error

      Servlet error: An exception occurred. The current application deployment descriptors do not allow for including it in this response. Please consult the application log for details.

      If I then use the following in my web.xml:

      <error-page>
      <error-code>500</error-code>
      /views/admin/error.xhtml
      </error-page>

      I get the correct page displayed.

      Why is this happenning? How could I maintain one place for all exceptions to be handled which allows all my exception messages to be shown?


      My enviornment is OC4J, Seam, RichFaces.


        • 1. Re: Newbie Problem with Exception handling and pages.xml
          Pete Muir Master

          Do you have seam's debug mode disabled, and facelets development mode turned off?

          Try posting with [ code ] tags

          • 2. Re: Newbie Problem with Exception handling and pages.xml
            Steven Headley Newbie

            Seams like have am now able to transfer to my error.xhtml page, but I have another problem. I don't have access to the xception message or anything dealing with the exception. I have tried 2 approaches:

            1. Create an Exception Listener:

            import java.io.PrintWriter;
            import java.io.StringWriter;
            import java.util.Iterator;
            import java.util.List;
            import java.util.Map;
            
            import javax.faces.event.PhaseEvent;
            import javax.faces.event.PhaseId;
            import javax.faces.event.PhaseListener;
            
            import org.jboss.seam.annotations.Logger;
            import org.jboss.seam.log.Log;
            import javax.faces.application.FacesMessage;
            import javax.faces.component.UIViewRoot;
            import javax.faces.context.ExternalContext;
            import javax.faces.context.FacesContext;
            import javax.servlet.ServletContext;
            import javax.servlet.ServletException;
            import javax.servlet.http.HttpServletRequest;
            import javax.servlet.http.HttpServletResponse;
            
            public class ExceptionListener implements PhaseListener{
            
            @Logger private Log log;
            static private FacesContext _instance = null;
            
            
             static public FacesContext getContext() {
             return _instance;
             }
            
            
             public void beforePhase(PhaseEvent event) {
             System.out.println("ExceptionListener BeforePhase: " + event.getPhaseId());
             String viewId = "/document/error.jsp";
            
             PhaseId phase = event.getPhaseId();
             if (phase == PhaseId.INVOKE_APPLICATION) {
            
             try {
             set_instance(event.getFacesContext());
            
            
             if (getContext() != null && getContext().getExternalContext() != null)
             {
             System.out.println("Analyzing context");
             // Any errors?
             String tracing = getStackTrace();
            
             System.out.println("trace found "+ tracing);
            
             // has information so place in message
             if(tracing.length() > 0)
             {
             UIViewRoot view = getContext().getApplication().getViewHandler().
             createView(getContext(), viewId);
             view.setViewId(viewId);
             getContext().setViewRoot(view);
             getContext().renderResponse();
             }
             else
             return;
             }
             }
             catch (Exception ex) {
             log.error(ex.getMessage());
             ex.printStackTrace();
             }
             }
             }
            
             public void afterPhase(PhaseEvent event) {
             System.out.println("ExceptionListener AfterPhase: " + event.getPhaseId());
             String viewId = "/document/error.jsp";
            
             PhaseId phase = event.getPhaseId();
             if (phase == PhaseId.INVOKE_APPLICATION) {
            
             try {
             System.out.println("Setting instance");
             set_instance(event.getFacesContext());
             System.out.println("getContext()");
             if (getContext() != null && getContext().getExternalContext() != null)
             {
             System.out.println("Analyzing context");
             // Any errors?
             String tracing = getStackTrace();
            
             System.out.println("[[[[trace found "+ tracing +" ]]]]");
            
             // has information so place in message
             if(tracing.length() > 0)
             {
             UIViewRoot view = getContext().getApplication().getViewHandler().
             createView(getContext(), viewId);
             view.setViewId(viewId);
             getContext().setViewRoot(view);
             getContext().renderResponse();
             }
             else
             return;
             }
             }
             catch (Exception ex) {
             log.error(ex.getMessage());
             ex.printStackTrace();
             }
             }
             }
            
             public PhaseId getPhaseId() {
             return PhaseId.INVOKE_APPLICATION;
             }
            
             public String getStackTrace() {
             System.out.println(">>>>getStackTrace()");
             Object codeObj = null, messageObj = null, typeObj = null;
            
             System.out.println("Get Request Map");
             ExternalContext xctx = getContext().getExternalContext();
             Object context = xctx.getContext();
             //
             if(context instanceof ServletContext){
             HttpServletRequest request = (HttpServletRequest)getContext().getExternalContext().getRequest();
             codeObj = request.getAttribute("javax.servlet.error.status_code");
             messageObj = request.getAttribute("javax.servlet.error.message");
             typeObj = request.getAttribute("javax.servlet.error.exception_type");
             }
            
             System.out.println("Get javax.servlet.error.exception");
            
            
             return messageObj.toString();
            
             }
            
             private void fillStackTrace(Throwable ex, PrintWriter pw) {
             if (null == ex) {
             return;
             }
            
             ex.printStackTrace(pw);
            
             if (ex instanceof ServletException) {
             Throwable cause = ((ServletException) ex).getRootCause();
            
             if (null != cause) {
             pw.println("Root Cause:");
             fillStackTrace(cause, pw);
             }
             } else {
             Throwable cause = ex.getCause();
            
             if (null != cause) {
             pw.println("Cause:");
             fillStackTrace(cause, pw);
             }
             }
             }
            
            
             public static void set_instance(FacesContext _instance) {
             ExceptionListener._instance = _instance;
             }
            }
            


            the other method that I used was to create an exception bean:

            @Stateful
            @Name("errorDisplayBean")
            @Scope(ScopeType.APPLICATION)
            @Synchronized
            @Startup
            public class ErrorDisplayBean implements ErrorDisplay{
             public String getStackTrace() {
             System.out.println(">>>>ErrorDisplayBean");
             FacesContext context = FacesContext.getCurrentInstance();
             Map request = context.getExternalContext().getRequestMap();
             Throwable ex = (Throwable) request.get("javax.servlet.error.exception");
             StringWriter sw = new StringWriter();
             PrintWriter pw = new PrintWriter(sw);
             fillStackTrace(ex, pw);
             return sw.toString();
             }
            
             private static void fillStackTrace(Throwable t, PrintWriter w) {
             if (t == null)
             return;
             t.printStackTrace(w);
             if (t instanceof ServletException) {
             Throwable cause = ((ServletException) t).getRootCause();
             if (cause != null) {
             w.println("Root cause:");
             fillStackTrace(cause, w);
             }
             } else if (t instanceof SQLException) {
             Throwable cause = ((SQLException) t).getNextException();
             if (cause != null) {
             w.println("Next exception:");
             fillStackTrace(cause, w);
             }
             } else {
             Throwable cause = t.getCause();
             if (cause != null) {
             w.println("Cause:");
             fillStackTrace(cause, w);
             }
             }
             }
            
             @Destroy @Remove
             public void destroy() {}
            }
            



            None of these methods returned anything concerning the exception that was thrown. In both cases I had seam debug mode and facelets development turned off.

            Thanks for your prompt help

            Regards

            • 3. Re: Newbie Problem with Exception handling and pages.xml
              Pete Muir Master

              There is a bug in Seam with displaying messages from exceptions.

              http://jira.jboss.com/jira/browse/JBSEAM-2139