6 Replies Latest reply on Jul 10, 2009 8:12 PM by Arbi Sookazian

    exception handling bug in seam(login and getters)

    Dean Hiller Expert

      We have been going through QA now and we added some special code for our QA to test


      1. exception on login (fail)
      2. exception on getter (fail but differen from login failure)
      3. exception on setter (fail but different than expected)
      3. exception on action methods (pass)



      It seams like the whole pages thing only works for action methods though I expected it was supposed to work for login and getters/setters as well...any exception at all.  This would be ideal...on any bug, we want to display a Sorry, you have encountered a problem in our appliation.  Please call customer support at XXXX to have this resolved and explain what you did to get this error.  Please tell support that this is a bug in the software


      Instead here are the results



      1. (login)redisplays the login page saying 'Transaction failed' and no user is going to know what the heck that means


      2. (getter)fails with a stack trace page....is there a way to hide this...I might try adding to web.xml here and see but I was hoping I would not have to and seam would cover it


      3. (setter) redisplays the page and puts the exception message into the error message on the page....DEFINITELY not what we want!!!!  We want to to to the error page and HIDE the message in the exception


      4. (action method) well, this is the only one that worked.

      Is anyone else having these problems? or is no one testing this out(which is I suspect the case as I know many seam developers not testing these scenarios out and assuming they work).


      thanks,
      Dean




        • 1. Re: exception handling bug in seam(login and getters)
          Arbi Sookazian Master

          This is an important topic (for production specifically).


          Here's what I have in my pages.xml regarding exceptions:


          <exception class="org.jboss.seam.framework.EntityNotFoundException">
                  <redirect view-id="/error.xhtml">
                      <message>Not found</message>
                  </redirect>
              </exception>
              
              <exception class="javax.persistence.EntityNotFoundException">
                  <redirect view-id="/error.xhtml">
                      <message>Not found</message>
                  </redirect>
              </exception>
              
              <exception class="javax.persistence.OptimisticLockException">
                  <end-conversation/>
                  <redirect view-id="/error.xhtml">
                      <message>Another user changed the same data, please try again</message>
                  </redirect>
              </exception>
              
              <exception class="org.jboss.seam.security.AuthorizationException">
                  <redirect view-id="/error.xhtml">
                      <message>You don't have permission to do this</message>
                  </redirect>
              </exception>
              
              <exception class="org.jboss.seam.security.NotLoggedInException">
                  <redirect view-id="/login.xhtml">
                      <message>Please log in first</message>
                  </redirect>
              </exception>
              
              <exception class="javax.faces.application.ViewExpiredException">
                  <redirect view-id="/error.xhtml">
                      <message>Your session has timed out, please try again</message>
                  </redirect>
              </exception>
               
              <exception>
                  <redirect view-id="/error.xhtml">
                      <message>Unexpected error, please try again</message>
                  </redirect>
              </exception>



          So I was under the (perhaps false) assumption that if any other exception is thrown and not handled in my classes, then the user would be redirected to error.xhtml page with Unexpected error, please try again.  So what does your pages.xml look like in this regard (i.e. exceptions)?  And how exactly does this catch-all exception work in Seam pages.xml?


          And do you have seam-debug turned off and facelets debug turned off as well in your QA envmt?


          web.xml:


          <context-param>
                <param-name>facelets.DEVELOPMENT</param-name>
                <param-value>@facelets-debug@</param-value>
             </context-param>



          components.xml:


          <core:init debug="@debug@" jndi-pattern="@jndiPattern@"/>



          I was unaware that Seam differentiates b/n exceptions that are thrown from action method and non-action methods like getters/setters.


          In any event, you don't want to display stack trace (of any kind) to the user but you very likely want to capture it somehow (e.g. logging) and then possibly trigger an immediate heads-up email to the dev team and/or helpdesk.  This would be a nice configurable addition to the Seam core as far as exception handling/notification is concerned...

          • 2. Re: exception handling bug in seam(login and getters)
            Arbi Sookazian Master

            On pg. 228 of the Yuan et al book, there is the following xml snippet:


            <exception class="java.lang.RuntimeException">
               <redirect view-id="/generalError.xhtml">
                  <message>Unexpected failure</message>
               </redirect>
            </exception>



            I don't see java.lang.RuntimeException in Seam 2.1.2.GA booking pages.xml.


            So is it best to use the above xml snippet for the catch-all exception or what I wrote before?


            <exception>
                    <redirect view-id="/error.xhtml">
                        <message>Unexpected error, please try again</message>
                    </redirect>
                </exception>

            • 3. Re: exception handling bug in seam(login and getters)
              Dean Hiller Expert

              RuntimeException is subclass of Exception so I doubt you would need that Runtime line....


              My exception is just about the same including the catchall as well.....


              I did make the mistake of having facelets dev on true, changing to false helped out some, but definitely did not fix all of it.  The setter is still failing with a richfaces button so maybe that the ajax exceptions are not handled well.  My seam debug is false.


              My pages....


                  <exception class="org.jboss.seam.framework.EntityNotFoundException">
                      <redirect view-id="/web/error.xhtml">
                          <message severity="warn">Record not found</message>
                      </redirect>
                  </exception>
              
                  <exception class="javax.persistence.EntityNotFoundException">
                      <redirect view-id="/web/error.xhtml">
                          <message severity="warn">Record not found</message>
                      </redirect>
                  </exception>
              
                  <exception class="javax.persistence.EntityExistsException">
                      <redirect view-id="/web/error.xhtml">
                          <message severity="warn">Duplicate record</message>
                      </redirect>
                  </exception>
              
                  <exception class="javax.persistence.OptimisticLockException">
                      <end-conversation/>
                      <redirect view-id="/web/error.xhtml">
                          <message severity="warn">Another user changed the same data, please try again</message>
                      </redirect>
                  </exception>
              
                  <exception class="org.jboss.seam.security.AuthorizationException">
                      <redirect view-id="/web/unauthorized.xhtml">
                          <message severity="error">You don't have permission to access this resource</message>
                      </redirect>
                  </exception>
              
                  <exception class="org.jboss.seam.security.NotLoggedInException">
                      <redirect view-id="/web/zlogin/login.xhtml">
                          <message severity="warn">#{messages['org.jboss.seam.NotLoggedIn']}</message>
                      </redirect>
                  </exception>
              
                  <exception class="javax.faces.application.ViewExpiredException">
                      <redirect view-id="/web/viewExpired.xhtml">
                          <message severity="warn">Your session has timed out, please try again</message>
                      </redirect>
                  </exception>
              
                  <exception class="org.jboss.seam.ConcurrentRequestTimeoutException" logLevel="trace">
                    <http-error error-code="503" />
                  </exception>
              
                  <exception>
                      <redirect view-id="/web/error.xhtml">
                          <message severity="error">Unexpected error, please try again</message>
                      </redirect>
                  </exception>
              





              • 4. Re: exception handling bug in seam(login and getters)
                Arbi Sookazian Master

                from SiA:



                When Facelets is running in development mode, it intercepts exceptions
                thrown in the Render Response phase. In that case, Seam’s exception-based
                routing will not kick in.

                we could test this by causing a NullPointerException, which is not in our exceptions list in pages.xml.


                String foo = null;
                foo.getClass();  //NPE thrown here, don't catch and see what happens!



                have you tried that?


                I just tried this and it works as intended with action handler method.


                Now trying with setter (added above code to generate NPE to my setter method):


                when I enter a value in the HtmlInputText and submit form, the postback occurs and this in console:


                11:02:29,931 ERROR [STDERR] Jul 10, 2009 11:02:29 AM javax.faces.component.UIInput updateModel
                SEVERE: /TestApplicationMetaData.xhtml @92,40 value="#{myTest1.foo}": Error writing 'foo' on type com.cox.ers.session.TestApplicationMetaDataAction_$$_javassist_6
                java.lang.NullPointerException
                     at com.cox.ers.session.TestApplicationMetaDataAction.setFoo(TestApplicationMetaDataAction.java:156)
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:585)
                     at org.jboss.seam.util.Reflections.invoke(Reflections.java:21)
                     at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:31)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
                     at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:46)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.persistence.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:48)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:31)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.core.ConversationInterceptor.aroundInvoke(ConversationInterceptor.java:65)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:42)
                     at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
                     at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
                     at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:166)
                     at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:102)
                     at com.cox.ers.session.TestApplicationMetaDataAction_$$_javassist_6.setFoo(TestApplicationMetaDataAction_$$_javassist_6.java)
                     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:585)
                     at javax.el.BeanELResolver.setValue(BeanELResolver.java:108)
                     at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:68)
                     at com.sun.faces.el.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:100)
                     at org.jboss.el.parser.AstPropertySuffix.setValue(AstPropertySuffix.java:73)
                     at org.jboss.el.parser.AstValue.setValue(AstValue.java:84)
                     at org.jboss.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
                     at com.sun.facelets.el.TagValueExpression.setValue(TagValueExpression.java:93)
                     at javax.faces.component.UIInput.updateModel(UIInput.java:771)
                     at javax.faces.component.UIInput.processUpdates(UIInput.java:703)
                     at javax.faces.component.UIForm.processUpdates(UIForm.java:261)
                     at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1076)
                     at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1076)
                     at org.ajax4jsf.component.AjaxViewRoot$2.invokeContextCallback(AjaxViewRoot.java:416)
                     at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:238)
                     at org.ajax4jsf.component.AjaxViewRoot.processUpdates(AjaxViewRoot.java:432)
                     at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
                     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
                     at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
                     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                     at jcifs.http.NtlmHttpFilter.doFilter(NtlmHttpFilter.java:125)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                     at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                     at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                     at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                     at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
                     at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
                     at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
                     at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
                     at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                     at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                     at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                     at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                     at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                     at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182)
                     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
                     at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
                     at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
                     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
                     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
                     at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                     at java.lang.Thread.run(Thread.java:595)
                11:02:30,337 INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.
                sourceId=j_id77:j_id78[severity=(ERROR 2), summary=(/TestApplicationMetaData.xhtml @92,40 value="#{myTest1.foo}": Error writing 'foo' on type com.cox.ers.session.TestApplicationMetaDataAction_$$_javassist_6), detail=(/TestApplicationMetaData.xhtml @92,40 value="#{myTest1.foo}": Error writing 'foo' on type com.cox.ers.session.TestApplicationMetaDataAction_$$_javassist_6)]
                



                No navigation to error.xhtml page as specified in pages.xml:


                <exception>
                        <redirect view-id="/error.xhtml">
                            <message>Unexpected error, please try again</message>
                        </redirect>
                    </exception>

                • 5. Re: exception handling bug in seam(login and getters)
                  Arbi Sookazian Master

                  I added this snippet to my pages.xml:


                  <exception class="java.lang.NullPointerException">
                          <redirect view-id="/error.xhtml">
                              <message>NPE occurred, please try again</message>
                          </redirect>
                      </exception>



                  and I got the same results as previous posting (does not redirect to error.xhtml and postback is successful with NPE stack trace in console).


                  What logic are you executing in your setter?  Have you tried to refactor that logic into a private method?  This seems like a bug/oversight in Seam's exception handling unless I'm missing something.  It works fine with the action method and my pre-existing pages.xml...

                  • 6. Re: exception handling bug in seam(login and getters)
                    Arbi Sookazian Master

                    On second thought, I have a feeling that the refactoring trick won't work b/c the problem/behavior is most likely associated with the current JSF life cycle being executed when the method executes and exception is thrown (i.e. perhaps it doesn't work with exceptions thrown from the Apply Request Values or Update model values phases but only works for exceptions from Invoke application phase).


                    It would be interesting to see if you experience this problem with Wicket or GWT, for example...