From 6bb9831bdac55d4d2f1e3f81d9d6402dff3d8e65 Mon Sep 17 00:00:00 2001 From: ryounes Date: Thu, 11 Aug 2011 22:03:19 +0000 Subject: [PATCH] NIHVIVO-3088 On error in Freemarker servlet processing, display stack trace to authorized users. --- .../freemarker/FreemarkerHttpServlet.java | 44 +++++++++++++------ .../TemplateResponseValues.java | 7 +-- .../web/templates/freemarker/body/about.ftl | 4 +- .../freemarker/body/error/error-display.ftl | 23 ++++++++++ 4 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 webapp/web/templates/freemarker/body/error/error-display.ftl diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java index 44f845bbe..b0023fb66 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/FreemarkerHttpServlet.java @@ -5,8 +5,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.Calendar; -import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -14,16 +12,15 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAccount; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.UseMiscellaneousAdminPages; import edu.cornell.mannlib.vitro.webapp.beans.ApplicationBean; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; -import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean; import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.TemplateProcessingHelper.TemplateProcessingException; @@ -35,7 +32,6 @@ import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.Red import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues; import edu.cornell.mannlib.vitro.webapp.email.FreemarkerEmailFactory; -import edu.cornell.mannlib.vitro.webapp.web.templatemodels.Tags; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import freemarker.ext.beans.BeansWrapper; @@ -57,6 +53,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { STANDARD_ERROR("error-standard.ftl"), ERROR_MESSAGE("error-message.ftl"), TITLED_ERROR_MESSAGE("error-titled.ftl"), + ERROR_DISPLAY("error-display.ftl"), MESSAGE("message.ftl"), TITLED_MESSAGE("message-titled.ftl"), PAGE_DEFAULT("page.ftl"), @@ -93,8 +90,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { vreq.setAttribute("freemarkerConfig", config); config.resetRequestSpecificSharedVariables(); - responseValues = processRequest(vreq); - + responseValues = processRequest(vreq); doResponse(vreq, response, responseValues); } catch (Throwable e) { @@ -112,7 +108,22 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { protected void handleException(VitroRequest vreq, HttpServletResponse response, Throwable t) throws ServletException { try { - doResponse(vreq, response, new ExceptionResponseValues(t, HttpServletResponse.SC_INTERNAL_SERVER_ERROR)); + int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + ExceptionResponseValues rv; + String templateName = Template.ERROR_DISPLAY.toString(); + if (PolicyHelper.isAuthorizedForActions(vreq, new UseMiscellaneousAdminPages())) { + Map map = new HashMap(); + Map errorData = new HashMap(); + errorData.put("errorMessage", t.getMessage()); + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + errorData.put("stackTrace", sw.toString()); + map.put("errorData", errorData); + rv = new ExceptionResponseValues(templateName, map, t, statusCode); + } else { + rv = new ExceptionResponseValues(templateName, t, statusCode); + } + doResponse(vreq, response, rv); } catch (TemplateProcessingException e) { throw new ServletException(); } @@ -206,7 +217,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { // Tell the template and any directives it uses that we're processing a page template. templateDataModel.put("templateType", PAGE_TEMPLATE_TYPE); - writePage(templateDataModel, config, vreq, response, values.getStatusCode()); + writePage(templateDataModel, config, vreq, response, values.getStatusCode(), values); } protected void doRedirect(HttpServletRequest request, HttpServletResponse response, ResponseValues values) @@ -256,8 +267,7 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { ResponseValues values) throws TemplateProcessingException { // Log the error, and display an error message on the page. log.error(values.getException(), values.getException()); - TemplateResponseValues trv = TemplateResponseValues.getTemplateResponseValuesFromException((ExceptionResponseValues)values); - doTemplate(vreq, response, trv); + doTemplate(vreq, response, values); } public String getThemeDir(ApplicationBean appBean) { @@ -408,9 +418,15 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { return processTemplate(values, config, request).toString(); } - protected void writePage(Map root, Configuration config, - HttpServletRequest request, HttpServletResponse response, int statusCode) throws TemplateProcessingException { - writeTemplate(getPageTemplateName(), root, config, request, response, statusCode); + protected void writePage(Map root, Configuration config, HttpServletRequest request, + HttpServletResponse response, int statusCode, ResponseValues rv) throws TemplateProcessingException { + + // For an error page, use the standard page template rather than a special one, in case that is the source + // of the error. (The standard page template could also be the source of the error, but that is + // less likely. + String pageTemplateName = + rv instanceof ExceptionResponseValues ? Template.PAGE_DEFAULT.toString() : getPageTemplateName(); + writeTemplate(pageTemplateName, root, config, request, response, statusCode); } protected void writeTemplate(String templateName, Map map, Configuration config, diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/responsevalues/TemplateResponseValues.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/responsevalues/TemplateResponseValues.java index b02ce7b0c..f150627eb 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/responsevalues/TemplateResponseValues.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/responsevalues/TemplateResponseValues.java @@ -47,11 +47,6 @@ public class TemplateResponseValues extends BaseResponseValues { public String getTemplateName() { return this.templateName; } - - public static TemplateResponseValues getTemplateResponseValuesFromException(ExceptionResponseValues responseValues) { - return new TemplateResponseValues(responseValues.getTemplateName(), - responseValues.getMap(), - responseValues.getStatusCode()); - } + } diff --git a/webapp/web/templates/freemarker/body/about.ftl b/webapp/web/templates/freemarker/body/about.ftl index a73b923a9..097d26ed6 100644 --- a/webapp/web/templates/freemarker/body/about.ftl +++ b/webapp/web/templates/freemarker/body/about.ftl @@ -4,10 +4,10 @@

${title}

-<#if aboutText??> +<#if aboutText?has_content>
${aboutText}
-<#if acknowledgeText??> +<#if acknowledgeText?has_content>
${acknowledgeText}
diff --git a/webapp/web/templates/freemarker/body/error/error-display.ftl b/webapp/web/templates/freemarker/body/error/error-display.ftl new file mode 100644 index 000000000..56196e2d3 --- /dev/null +++ b/webapp/web/templates/freemarker/body/error/error-display.ftl @@ -0,0 +1,23 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for general system error. --> + +

+ There was an error in the system. + <#-- This error has been reported to the site administrator. --> +

+ +<#if errorData??> <#-- view for site administrators --> + <#if errorData.errorMessage?has_content> +

Error message: ${errorData.errorMessage}

+ + <#if errorData.stackTrace?has_content> +
+

Stack trace (full trace available in the vivo log):

+ ${errorData.stackTrace} +
+ +<#elseif ! urls.currentPage?ends_with("home")> <#-- view for other users --> +

Return to the home page.

+ +