Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
1.3
-
None
Description
When VelocityViewServlet reports and error (e.g. if an exception is thrown from a $reference.method()), it returns a detailed error page with status 200.
This interoperates with the web container poorly, as it cannot be caught and redirected to a nice error page in a production environment (e.g. through the <error-page> mechanism in web.xml).
This is complicated by the fact that VelocityViewServlet writes directly to the HttpResponseServlet writer, so once the template processing has begun, it is no longer possible to call HttpServletResponse.sendError() and send, say, a "500 Internal Server Error", which would be more appropriate.
Here is a patch: change VelocityViewServlet.mergeTemplate() so that it buffers to a StringWriter, and only writes to the HttpServletResponse writer after the merge is completed.
This way, users can override VelocityViewServlet.error() to call response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR) if desired.
protected void mergeTemplate(Template template,
Context context,
HttpServletResponse response)
throws ResourceNotFoundException, ParseErrorException,
MethodInvocationException, IOException,
UnsupportedEncodingException, Exception
{
VelocityWriter vw = null;
// write to a temporary string buffer, so that if we have to bail
// and call HttpServletResponse.sendError(), we still can – bs
//Writer writer = getResponseWriter(response);
StringWriter sw = new StringWriter();
try
{
vw = (VelocityWriter)writerPool.get();
if (vw == null)
else
{ vw.recycle(sw); } performMerge(template, context, vw);
}
finally
{
if (vw != null)
{
try
catch (Exception e)
{ velocity.getLog().debug("VelocityViewServlet: " + "Trouble releasing VelocityWriter: " + e.getMessage()); } }
}
}