Commits

rainerh  committed 9977ac0

Backport of Problem Report page within devMode
Issue number:
Obtained from:
Submitted by:
Reviewed by:

git-svn-id: http://svn.opensymphony.com/svn/webwork/trunk@2690573baa09-0c28-0410-bef9-dab3c582ae83

  • Participants
  • Parent commits de92cc5

Comments (0)

Files changed (2)

File src/java/com/opensymphony/webwork/dispatcher/DispatcherUtils.java

 import com.opensymphony.webwork.ServletActionContext;
 import com.opensymphony.webwork.WebWorkStatics;
 import com.opensymphony.webwork.WebWorkConstants;
+import com.opensymphony.webwork.views.freemarker.FreemarkerManager;
 import com.opensymphony.webwork.config.Configuration;
 import com.opensymphony.webwork.dispatcher.mapper.ActionMapping;
 import com.opensymphony.webwork.dispatcher.multipart.MultiPartRequest;
 import com.opensymphony.xwork.interceptor.component.ComponentInterceptor;
 import com.opensymphony.xwork.interceptor.component.ComponentManager;
 import com.opensymphony.xwork.util.*;
+import com.opensymphony.xwork2.util.location.Location;
+import com.opensymphony.xwork2.util.location.LocationUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.IOException;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
+import java.util.*;
+
+import freemarker.template.Template;
 
 /**
  * A utility class whereby FilterDispatcher delegate most of its tasks to. A static
     }
 
     protected void cleanup() {
-    	ObjectFactory objectFactory = ObjectFactory.getObjectFactory();
-    	if (objectFactory == null) {
-    		LOG.warn("Object Factory is null, something is seriously wrong, no clean up will be performed");
-    	}
-    	if (objectFactory instanceof ObjectFactoryDestroyable) {
-    		try {
-    			((ObjectFactoryDestroyable)objectFactory).destroy();
-    		}
-    		catch(Exception e) {
-    			// catch any exception that may occured during destroy() and log it
-    			LOG.error("exception occurred while destroying ObjectFactory ["+objectFactory+"]", e);
-    		}
-    	}
+        ObjectFactory objectFactory = ObjectFactory.getObjectFactory();
+        if (objectFactory == null) {
+            LOG.warn("Object Factory is null, something is seriously wrong, no clean up will be performed");
+        }
+        if (objectFactory instanceof ObjectFactoryDestroyable) {
+            try {
+                ((ObjectFactoryDestroyable)objectFactory).destroy();
+            }
+            catch(Exception e) {
+                // catch any exception that may occured during destroy() and log it
+                LOG.error("exception occurred while destroying ObjectFactory ["+objectFactory+"]", e);
+            }
+        }
     }
 
     protected void init(ServletContext servletContext) {
-    	boolean reloadi18n = Boolean.valueOf((String) Configuration.get(WebWorkConstants.WEBWORK_I18N_RELOAD)).booleanValue();
+        boolean reloadi18n = Boolean.valueOf((String) Configuration.get(WebWorkConstants.WEBWORK_I18N_RELOAD)).booleanValue();
         LocalizedTextUtil.setReloadBundles(reloadi18n);
 
         if (Configuration.isSet(WebWorkConstants.WEBWORK_OBJECTFACTORY)) {
         }
 
         //check for configuration reloading
-        if (Configuration.isSet(WebWorkConstants.WEBWORK_CONFIGURATION_XML_RELOAD) && 
-        		"true".equalsIgnoreCase(Configuration.getString(WebWorkConstants.WEBWORK_CONFIGURATION_XML_RELOAD))) {
+        if (Configuration.isSet(WebWorkConstants.WEBWORK_CONFIGURATION_XML_RELOAD) &&
+                "true".equalsIgnoreCase(Configuration.getString(WebWorkConstants.WEBWORK_CONFIGURATION_XML_RELOAD))) {
             FileManager.setReloadingConfigs(true);
         }
 
             }
         } catch (ConfigurationException e) {
             LOG.error("Could not find action", e);
-            sendError(request, response, HttpServletResponse.SC_NOT_FOUND, e);
+            sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
         } catch (Exception e) {
             String msg = "Could not execute action";
             LOG.error(msg, e);
-            throw new ServletException(msg, e);
+            sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
         }
     }
 
      * @param code     the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible error codes).
      * @param e        the Exception that is reported.
      */
-    public void sendError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
-        try {
-            // send a http error response to use the servlet defined error handler
-            // make the exception availible to the web.xml defined error page
-            request.setAttribute("javax.servlet.error.exception", e);
+    public void sendError(HttpServletRequest request, HttpServletResponse response, ServletContext ctx, int code, Exception e) {
+        if (devMode) {
+            response.setContentType("text/html");
+
+            try {
+                freemarker.template.Configuration config = FreemarkerManager.getInstance().getConfiguration(ctx);
+                Template template = config.getTemplate("/com/opensymphony/webwork/dispatcher/error.ftl");
+
+                List<Throwable> chain = new ArrayList<Throwable>();
+                Throwable cur = e;
+                chain.add(cur);
+                while ((cur = cur.getCause()) != null) {
+                    chain.add(cur);
+                }
 
-            // for compatibility
-            request.setAttribute("javax.servlet.jsp.jspException", e);
+                HashMap<String,Object> data = new HashMap<String,Object>();
+                data.put("exception", e);
+                data.put("unknown", Location.UNKNOWN);
+                data.put("chain", chain);
+                data.put("locator", new Locator());
+                template.process(data, response.getWriter());
+                response.getWriter().close();
+            } catch (Exception exp) {
+                try {
+                    response.sendError(code, "Unable to show problem report: " + exp);
+                } catch (IOException ex) {
+                    // we're already sending an error, not much else we can do if more stuff breaks
+                }
+            }
+        } else {
+            try {
+                // send a http error response to use the servlet defined error handler
+                // make the exception availible to the web.xml defined error page
+                request.setAttribute("javax.servlet.error.exception", e);
 
-            // send the error response
-            response.sendError(code, e.getMessage());
-        } catch (IOException e1) {
-            // we're already sending an error, not much else we can do if more stuff breaks
+                // for compatibility
+                request.setAttribute("javax.servlet.jsp.jspException", e);
+
+                // send the error response
+                response.sendError(code, e.getMessage());
+            } catch (IOException e1) {
+                // we're already sending an error, not much else we can do if more stuff breaks
+            }
         }
     }
 
     public static void setPortletSupportActive(boolean portletSupportActive) {
         DispatcherUtils.portletSupportActive = portletSupportActive;
     }
+
+   /** Simple accessor for a static method */
+    public class Locator {
+        public Location getLocation(Throwable t) {
+            return LocationUtils.getLocation(t);
+        }
+    }
 }

File src/java/com/opensymphony/webwork/dispatcher/error.ftl

+<html>
+<head>
+    <title>WebWork Problem Report</title>
+</head>
+<body>
+    <h2>WebWork Problem Report</h2>
+    <p>
+    WebWork has detected an unhandled exception:
+    </p>
+
+<#assign msgs = [] />
+<#list chain as ex>
+    <#if ex.message?exists>
+        <#assign msgs = [ex.message] + msgs/>
+    </#if>
+</#list>
+<#assign rootex = exception/>
+<#list chain as ex>
+    <#if (ex.location?exists && (ex.location != unknown))>
+        <#assign rootloc = ex.location/>
+        <#assign rootex = ex/>
+    <#else>
+            <#assign tmploc = locator.getLocation(ex) />
+            <#if (tmploc != unknown)>
+            <#assign rootloc = tmploc/>
+                <#assign rootex = ex/>
+            </#if>
+    </#if>
+</#list>
+
+<div id="exception-info">
+<table>
+    <tr>
+        <td><strong>Messages</strong>:</td>
+        <td>
+            <#if (msgs?size > 1)>
+            <ol>
+                <#list msgs as msg>
+                    <li>${msg}</li>
+                </#list>
+            </ol>
+            <#elseif (msgs?size == 1)>
+                ${msgs[0]}
+            </#if>
+        </td>
+    </tr>
+    <#if rootloc?exists>
+    <tr>
+        <td><strong>File</strong>:</td>
+        <td>${rootloc.URI}</td>
+    </tr>
+    <tr>
+        <td><strong>Line number</strong>:</td>
+        <td>${rootloc.lineNumber}</td>
+    </tr>
+    <#if (rootloc.columnNumber >= 0)>
+    <tr>
+        <td><strong>Column number</strong>:</td>
+        <td>${rootloc.columnNumber}</td>
+    </tr>
+    </#if>
+    </#if>
+
+</table>
+</div>
+
+<#if rootloc?exists>
+    <#assign snippet = rootloc.getSnippet(2) />
+    <#if (snippet?size > 0)>
+        <div id="snippet">
+        <hr />
+
+            <#list snippet as line>
+                <#if (line_index == 2)>
+                        <#if (rootloc.columnNumber >= 0)>
+                        <pre style="background:yellow">${(line[0..(rootloc.columnNumber-3)]?html)}<span style="background:red">${(line[(rootloc.columnNumber-2)]?html)}</span><#if ((rootloc.columnNumber)<line.length())>${(line[(rootloc.columnNumber-1)..]?html)}</#if></pre>
+                    <#else>
+                            <pre style="background:yellow">${line?html}</pre>
+                    </#if>
+                <#else>
+                    <pre>${line?html}</pre>
+                </#if>
+            </#list>
+        </div>
+    </#if>
+</#if>
+
+<div id="stacktraces">
+<hr />
+<h3>Stacktraces</h3>
+<#list chain as ex>
+<div class="stacktrace" style="padding-left: ${ex_index * 2}em">
+    <strong>${ex}</strong>
+    <div>
+    <pre>
+    <#list ex.stackTrace as frame>
+    ${frame}
+    </#list>
+    </pre>
+    </div>
+</div>
+</#list>
+</div>
+
+<div class="footer">
+<hr />
+<p>
+You are seeing this page because development mode is enabled.  Development mode, or devMode, enables extra
+debugging behaviors and reports to assist developers.  To disable this mode, set:
+<pre>
+  webwork.devMode=false
+</pre>
+in your <code>WEB-INF/classes/webwork.properties</code> file.
+</p>
+</div>
+</body>
+</html>