dev@javaserverfaces.java.net

[REVIEW] Ensure ViewExpiredException isn't wrapped when detected

From: Ryan Lubke <Ryan.Lubke_at_sun.com>
Date: Tue, 08 Nov 2005 13:01:08 -0800

With the current RI implementation, a developer currently can't
add the following to their web.xml:

<error-page>
        
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
        <location>/error.jsp</location>
 </error-page>

and expect the error page to be triggered since the Lifecycle implementation
wraps all caught exceptions as a FacesException.

Modify the lifecycle to rethrow ViewExpiredExceptions when found.

Tested with a simple app locally to confirm that the error page is now
triggered.


SECTION: Modified Files
----------------------------
M src/com/sun/faces/lifecycle/LifecycleImpl.java
 - if 'ex' is a ViewExpiredException, rethrow
 - for the other case, unwind the exception chain
   and throw a new FacesException with the root
   cause of the chain


SECTION: Diffs
----------------------------
Index: src/com/sun/faces/lifecycle/LifecycleImpl.java
===================================================================
RCS file:
/cvs/javaserverfaces-sources/jsf-ri/src/com/sun/faces/lifecycle/LifecycleImpl.java,v
retrieving revision 1.56
diff -u -r1.56 LifecycleImpl.java
--- src/com/sun/faces/lifecycle/LifecycleImpl.java 26 Aug 2005
15:27:08 -0000 1.56
+++ src/com/sun/faces/lifecycle/LifecycleImpl.java 8 Nov 2005
20:23:37 -0000
@@ -34,6 +34,7 @@
 import java.util.logging.Level;
 
 import javax.faces.FacesException;
+import javax.faces.application.ViewExpiredException;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseEvent;
 import javax.faces.event.PhaseId;
@@ -247,7 +248,7 @@
                 }
             }
     }
- catch (Throwable e) {
+ catch (Exception e) {
         if (logger.isLoggable(Level.WARNING)) {
                 logger.warning("phase(" + phaseId.toString() + "," +
context +
               ") threw exception: " + e + " " + e.getMessage() +
@@ -295,7 +296,14 @@
         // Allow all afterPhase listeners to execute before throwing the
         // exception caught during the phase execution.
         if (exceptionThrown) {
- throw new FacesException(ex.getCause());
+ if (ex instanceof ViewExpiredException) {
+ throw (ViewExpiredException) ex;
+ }
+ // unwind exceptions to root cause
+ while (ex.getCause() != null) {
+ ex = ex.getCause();
+ }
+ throw new FacesException(ex);
         }
     }