4 Replies Latest reply on Mar 10, 2010 8:57 PM by nbelaevski

    exception management...

    agallo73

      Hello, I'd like to use a proper approach for  Exception handling.

       

      I'd like to catch all the possible exceptions in a centralized place and then redirect the normal flow to a facelet if some error occurrs.

       

      I saw many articles using filters, phase listeners and redirecting to a jsp page but I did not find anything as far as facelets are concerned.

       

       

      The web flow of my application happens within a wizard and I'd like to  keep the flow within the wizard also when an exception occurs.

       

       

      May you provide some code or technical article to point to?

       

      When Ajax rendering is concerned exception management is more complicated and I think that there should be a good strategy to follow.

       

      May some one provide some hint please?

       

      This is the code in an article I found...but it works for jsp. How mcan I change it to work with facelets?

       

       

      public class FacesServletWrapper extends HttpServlet
          {
              private FacesServlet facesServletDelegate;
              private static final String ERROR_PAGE = "serverErrorPage";
              private String serverErrorPage;
          public void init(ServletConfig servletConfig) throws ServletException
          {
              facesServletDelegate= new FacesServlet();
              facesServletDelegate.init(servletConfig);
              serverErrorPage = servletConfig.getInitParameter(ERROR_PAGE);
          }
          public void destroy()
          {
              facesServletDelegate.destroy();
          }
          public ServletConfig getServletConfig()
          {
              return facesServletDelegate.getServletConfig();
          }
          public String getServletInfo()
          {
              return facesServletDelegate.getServletInfo();
          }
         
          private FacesContext getFacesContext(final ServletRequest request, final ServletResponse response) {

       

              FacesContext facesContext = FacesContext.getCurrentInstance();
              if (facesContext != null) {
              return facesContext;
              }

       

              FacesContextFactory contextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder. FACES_CONTEXT_FACTORY);
              LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder. LIFECYCLE_FACTORY);
              Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory. DEFAULT_LIFECYCLE);

       

              facesContext = contextFactory.getFacesContext(this.getServletContext(), request, response, lifecycle);
              UIViewRoot view = facesContext.getApplication().getViewHandler().createView(facesContext, "yourOwnID");
              facesContext.setViewRoot(view);
              return facesContext;
              }

       

          public void service(ServletRequest request, ServletResponse response)
                      throws ServletException, IOException
          {
              try
              {
                  facesServletDelegate.service(request,response);
              }
              catch(Throwable e)
              {
                 
                  System.out.println("eccezione intercettata");
                 redirectToServerErrorPage((HttpServletRequest) request,
                                     (HttpServletResponse) response);
             
              /*

                  FacesContext facesCtx = getFacesContext(request,response);
                  Application app = facesCtx.getApplication();
                  ELContext elContext = FacesContext.getCurrentInstance().getELContext();
                  TrasformBean trasformBean = (TrasformBean) app.getELResolver()
                          .getValue(elContext, null, "trasformBean");
                 
                      NavigationHandler navigationHandler = app.getNavigationHandler();

       

                      trasformBean.setViewId("/main.xhtml");
                      navigationHandler.handleNavigation(facesCtx, null,
                              "exceptionCaught");
                      facesCtx.renderResponse();

      */
                 
              }
          }
          private void redirectToServerErrorPage(HttpServletRequest request,
                       HttpServletResponse response) throws IOException
          {
              if (!serverErrorPage.equals(""))
              {
                  response.sendRedirect(request.getContextPath() + serverErrorPage);
              }
          }
         
          }

        • 1. Re: exception management...
          agallo73

          I also want to stress that with richfaces  it's very difficult to catch all the exceptions since, depending on a listener being invoked, an action being performed, and depending on ajax support being involved or not, exceptions are caught by filters  and phase listeners or not.

           

          I'd like to see some replies in a technical forum.

           

          I already posted some interesting questions as far as some problems regarding media output and the rendering of office related documents but I did not have any answer.

           

          In these situations I think that, with great disconfourt, I'd seriously consider the idea of switching to JSF  2.0 as soon as possible.

           

          May someone help me please?

          • 2. Re: exception management...
            nbelaevski

            Antonio,

             

            I've replied about displaying office documents: http://community.jboss.org/message/530560#530560 .

             

            Can you please clarify more on your issues with exceptions handling? I see that RichFaces filter catches ViewExpiredException for AJAX requests when user sets handleViewExpiredOnClient=true, however it should be catching it, also you can switch this feature off.

             

            There are problems with exceptions handling in JSF 1.2 - e.g. exceptions from ActionListener are swallowed, but that are issues of JSF specification, we just follow it there. JSF 2.0 addresses the problem of swallowed exceptions, so it can make sense to migrate, however as RichFaces is not a JSF implementation, but extension, you can still continue using RichFaces and have JSF 2.0.

            • 3. Re: exception management...
              agallo73

              Hi Nick , thanks for your collaboration.

               

              I'm using

               

              <context-param>
                          <param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name>
                          <param-value>true</param-value>
                      </context-param>

               

              and using documented code:

               

              A4J.AJAX.onExpired = function(loc, expiredMsg){

               

                  if(window.confirm("La sessione e' spirata e non puo' essere ripristinata; vuoi ricaricare la pagina?  All'indirizzo : "+loc)){

               

                    return loc;

               

                  } else {

               

                   return false;

               

                  }

               

              }

               

              A4J.AJAX.onError = function(req, status, message){

               

                  window.alert("Custom onError handler "+message);

               

              }

               

               

               

               

              and  I properly get an ajax warning message when the session times out.

               

              However  when an  error (that should be managed by the script in bold) occurrs, the relative message only shows up in some circumstances and does not appear when an exception is thrown. It should catch client side errors but my application logic is on server. So what should I do?

               

              I'm getting mad with exception management.

              I'm trying any thing, filters, phase listeners and so on.

               

              In some cases the error message appears, in other the filter catches the exception, in other the exception is never caught.

               

              As an example, I'm using some libraries to convert documents to pdf.

               

              When conversion happens after file uploading in the file upload listner code the filter detects the exception.....

               

              When, instead, the exception arises from a method being called from a button's listener, the exception is not caught by the filter.

               

              I'd like to have some centralized code in a filter or a listner that would be able to catch all exceptions and redirect the user to a error facelet using some code like this....

               

              FacesContext facesContext = FacesContext.getCurrentInstance();

               

              Application app = facesCtx.getApplication();
                         
              NavigationHandler navigationHandler = app.getNavigationHandler();

               

              navigationHandler.handleNavigation(facesCtx, null,
                                      "exceptionCaught");
                              facesCtx.renderResponse();

               

               

              where exceptionCaught is related to a navigation page in the faces-config.xml file

               

              In the servlet this code does not work since it complains of a null view root. You can find the code used to create the FaceContext in the  post above.

               

              Can you provide me with some suggestion as fa as a code that might fit all the situations, if any?

              • 4. Re: exception management...
                nbelaevski

                Not much to recommend. Exceptions for action listeners are wrapped here: javax.faces.event.MethodExpressionActionListener.processAction(ActionEvent) and these listeners are created by Facelets tag handlers that is not possible to override.

                 

                Currently you can:

                 

                1) Try JSF 2 (check wiki page about JSF 2 & RF)

                2) Use ActionListener interface, not action listener methods

                3) Provide your own ExpressionFactory via custom Application object that will create MethodExpression objects (wrap existing) by introducing additional handling for ELException e.g. re-throwing them as another ones (like some sort of FacesException).