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 b0023fb66..4cf87cd1a 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 @@ -2,9 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.controller.freemarker; +import static javax.mail.Message.RecipientType.TO; + import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Date; import java.util.HashMap; import java.util.Map; @@ -21,6 +24,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOwnAcc 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.ConfigurationProperties; 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; @@ -32,6 +36,7 @@ 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.email.FreemarkerEmailMessage; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.User; import edu.cornell.mannlib.vitro.webapp.web.templatemodels.menu.MainMenu; import freemarker.ext.beans.BeansWrapper; @@ -50,14 +55,22 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { public static final String BODY_TEMPLATE_TYPE = "body"; protected enum Template { - 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"), + + SETUP("setup.ftl"), + PAGE_DEFAULT("page.ftl"), - SETUP("setup.ftl"); + + // error templates + ERROR_DISPLAY("error-display.ftl"), + ERROR_EMAIL("error-email.ftl"), + ERROR_MESSAGE("error-message.ftl"), + STANDARD_ERROR("error-standard.ftl"), + TITLED_ERROR_MESSAGE("error-titled.ftl"), + + // message templates + MESSAGE("message.ftl"), + TITLED_MESSAGE("message-titled.ftl"); + private final String filename; @@ -105,25 +118,61 @@ public class FreemarkerHttpServlet extends VitroHttpServlet { } } - + /** In case of a processing error, display an error page. To an authorized user, the page displays + * details of the error. Otherwise, these details are sent to the site administrator. + */ protected void handleException(VitroRequest vreq, HttpServletResponse response, Throwable t) throws ServletException { try { - int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; - ExceptionResponseValues rv; + Map templateMap = new HashMap(); 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); + int statusCode = HttpServletResponse.SC_INTERNAL_SERVER_ERROR; + + // adminErrorData will be viewable only by an admin, either on the + // page or in an email. + Map adminErrorData = new HashMap(); + + StringBuffer requestedUrl = vreq.getRequestURL(); + String queryString = vreq.getQueryString(); + if (queryString != null) { + requestedUrl.append(queryString); + } + adminErrorData.put("requestedUrl", requestedUrl); + + String errorMessage = t.getMessage(); + adminErrorData.put("errorMessage", errorMessage); + + StringWriter sw = new StringWriter(); + t.printStackTrace(new PrintWriter(sw)); + String stackTrace = sw.toString(); + adminErrorData.put("stackTrace", stackTrace); + + adminErrorData.put("datetime", new Date()); + + templateMap.put("errorOnHomePage", this instanceof HomePageController); + + boolean sentEmail = false; + + // If the user is authorized, display the error data on the page + if (PolicyHelper.isAuthorizedForActions(vreq, new UseMiscellaneousAdminPages())) { + templateMap.put("adminErrorData", adminErrorData); + + // Else send the data to the site administrator } else { - rv = new ExceptionResponseValues(templateName, t, statusCode); - } + FreemarkerEmailMessage email = FreemarkerEmailFactory.createNewMessage(vreq); + String recipient = ConfigurationProperties.getBean(getServletContext()) + .getProperty("email.replyTo"); + email.addRecipient(TO, recipient); + email.setTemplate(Template.ERROR_EMAIL.toString()); + email.setBodyMap(adminErrorData); + email.processTemplate(); + sentEmail = email.send(); + } + + templateMap.put("sentEmail", sentEmail); + + ExceptionResponseValues rv = new ExceptionResponseValues(templateName, templateMap, t, statusCode); doResponse(vreq, response, rv); + } catch (TemplateProcessingException e) { throw new ServletException(); } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java index 5d3aaf0ef..455e433a7 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/email/FreemarkerEmailMessage.java @@ -167,7 +167,7 @@ public class FreemarkerEmailMessage { } } - public void send() { + public boolean send() { try { MimeMessage msg = new MimeMessage(session); msg.setReplyTo(new Address[] { replyToAddress }); @@ -204,9 +204,10 @@ public class FreemarkerEmailMessage { msg.setSentDate(new Date()); Transport.send(msg); - + return true; } catch (MessagingException e) { log.error("Failed to send message.", e); + return false; } } diff --git a/webapp/web/templates/freemarker/body/error/error-display.ftl b/webapp/web/templates/freemarker/body/error/error-display.ftl index 56196e2d3..6bece3ccf 100644 --- a/webapp/web/templates/freemarker/body/error/error-display.ftl +++ b/webapp/web/templates/freemarker/body/error/error-display.ftl @@ -4,20 +4,22 @@

There was an error in the system. - <#-- This error has been reported to the site administrator. --> + <#if sentEmail> + 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 adminErrorData??> <#-- view for site administrators --> + <#if adminErrorData.errorMessage?has_content> +

Error message: ${adminErrorData.errorMessage}

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

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

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

Return to the home page.

diff --git a/webapp/web/templates/freemarker/body/error/error-email.ftl b/webapp/web/templates/freemarker/body/error/error-email.ftl new file mode 100644 index 000000000..f5265280c --- /dev/null +++ b/webapp/web/templates/freemarker/body/error/error-email.ftl @@ -0,0 +1,49 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for email message sent to site administrator when an error occurs on the site. --> + +<#assign subject = "An error occurred on the VIVO site" /> + +<#assign datetime = datetime?string("yyyy-MM-dd HH:mm:ss zzz")> + +<#assign html> + + + ${subject} + + +

+ An error occurred on your VIVO site at ${datetime}. +

+ +

+ Requested url: ${requestedUrl}. +

+ +

+ Error message: ${errorMessage}. +

+ +

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

+ +
${stackTrace}
+ + + + + +<#assign text> +An error occurred on your VIVO site at ${datetime}. + +Requested url: ${requestedUrl}. + +Error message: ${errorMessage}. + +Stack trace (full trace available in the vivo log): + +${stackTrace} + + +<@email subject=subject html=html text=text /> \ No newline at end of file