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.