dev@javaserverfaces.java.net

Review for Mojarra issue 1505?

From: Andy Schwartz <andy.g.schwartz_at_gmail.com>
Date: Wed, 13 Jan 2010 16:13:48 -0500

Gang -

Could anyone take a quick look at my proposed fix for this issue?

Oh, and... I haven't run the Mojarra tests yet to verify that this
doesn't break anything. It's been a while... could someone remind me
how to do this?

Andy



---------- Forwarded message ----------
Date: Wed, Jan 13, 2010 at 4:03 PM
Subject: [Issue 1505] New - Exceptions hidden during executePageToBuildView()


https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1505
                Issue #|1505
                Summary|Exceptions hidden during executePageToBuildView()
              Component|javaserverfaces
                Version|2.0.1
               Platform|All
             OS/Version|All
                    URL|
                 Status|NEW
      Status whiteboard|
               Keywords|
             Resolution|
             Issue type|DEFECT
               Priority|P3
           Subcomponent|JSP
            Assigned to|javaserverfowner
            Reported by|aschwart






------- Additional comments from aschwart_at_dev.java.net Wed Jan 13
21:03:33 +0000 2010 -------
Note: the problem described here is specific to JSP.  Facelets should be fine.

The test case is any JSP page that contains some non-valid content -
eg. a typo in a tag name.  In this
case an exception is thrown and is properly handed off to the ExceptionHandler.
ExceptionHandlerImpl.throwIt() handles this as follows:

   private void throwIt(FacesContext ctx, FacesException fe) {

       boolean isDevelopment = ctx.isProjectStage(ProjectStage.Development);
       if (isDevelopment && !errorPagePresent) {
           RenderKitUtils.renderHtmlErrorPage(ctx, fe);
       } else {
           if (isDevelopment) {
               ctx.getExternalContext().getRequestMap().put("com.sun.faces.error.view",
ctx.getViewRoot());
           }
           throw fe;
       }
   }

When the development project stage is used, we expect to see a nice
HTML error page as rendered by
renderHtmlErrorPage().  But we don't.  Instead we get a status code
500 response with no HTML
payload.

What's the deal?

It turns out that when renderHtmlErrorPage() retrieves the Writer, it
ends up getting an instance of
com.sun.faces.application.WebPrintWriter that eats any written
content.  The WebPrintWriter is set up by
com.sun.faces.application.ViewHandlerResponseWrapper, which is a
response wrapper that is installed
by JspViewHandlingStrategy.executePageToBuildView just before
dispatching the request on to the JSP:


       // replace the response with our wrapper
       ViewHandlerResponseWrapper wrapped = getWrapper(extContext);
       extContext.setResponse(wrapped);

       // build the view by executing the page
       extContext.dispatch(requestURI);

       if (LOGGER.isLoggable(Level.FINE)) {
           LOGGER.fine("After dispacthMessage to viewId " + requestURI);
       }

       // replace the original response
       extContext.setResponse(originalResponse);

Note that the response wrapper is removed just after the dispatch.
However, the clean up code is not
in a finally block, so if an exception is thrown during the dispatch,
the WebPrintWriter remains installed
and as a result our HTML error page contents are written to /dev/null
instead of to the actual response
stream.

The funny thing is that the problem is only really noticeable in the
development project stage.  In other
project stages ExceptionHandlerImpl re-throws the exception, so, while
we don't see the nice HTML
error page, we at least see the exception message/stack.