[Yanel-dev] Generic exception handler

Cedric Staub cedric.staub at wyona.com
Mon Jan 24 11:03:52 CET 2011


Hello there!

I wrote a resource called generic-exception-handler, which is called
whenever an exception is thrown while a request is being processed.
Yanel had this functionality built-in until now, but that made it
impossible to overwrite the exception-handler with a custom version.

With this extension it's possible to write your own custom exception
handler and overwrite the generic exception handler's global resource
config. That way you can get rid of the Yanel-specific error pages and
install you own ones ;-).

Note: The exception and stack trace are logged but not displayed in the 
browser. I don't feel the user needs to know the details of the inner
workings of the application. The dev or sysadmin can just look at the
logs anyway, and I feel stack traces are confusing to users. 

But what to others think? Stack trace: yes or no?

Cheers
Cedric

PS: The patch is just a preview, I'll post the full patch to Yanel's
bugzilla. I also attached a screenshot for preview purposes.
-------------- next part --------------
Index: src/contributions/resources/generic-exception-handler/src/build/dependencies.xml
===================================================================
--- src/contributions/resources/generic-exception-handler/src/build/dependencies.xml	(revision 0)
+++ src/contributions/resources/generic-exception-handler/src/build/dependencies.xml	(revision 0)
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<project name="generic-exception-handler-dependencies" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
+
+  <target name="dependencies" description="Dependencies">
+    <artifact:remoteRepository id="wyona.remote.repository" url="${maven.url}"/>
+
+    <artifact:dependencies pathId="maven2.classpath" filesetId="maven2.fileset">
+      <remoteRepository refid="wyona.remote.repository"/>
+      <dependency groupId="wyona-org-yanel" artifactId="yanel-core" version="${yanel.source.version}"/>
+      <dependency groupId="wyona-org-yanel" artifactId="yanel-impl" version="${yanel.source.version}"/>
+    </artifact:dependencies>
+
+    <artifact:dependencies pathId="maven2.resource.classpath" filesetId="maven2.resource.fileset">
+      <remoteRepository refid="wyona.remote.repository"/>
+      <!-- No resource specific libs yet -->
+    </artifact:dependencies>
+
+    <property name="maven2.cp" refid="maven2.classpath"/>
+    <!--<echo>Maven2 classpath: ${maven2.cp}</echo>-->
+  </target>
+
+</project>
Index: src/contributions/resources/generic-exception-handler/src/build/build.properties
===================================================================
--- src/contributions/resources/generic-exception-handler/src/build/build.properties	(revision 0)
+++ src/contributions/resources/generic-exception-handler/src/build/build.properties	(revision 0)
@@ -0,0 +1,2 @@
+resource.name=generic-exception-handler
+resource.version=0.0.1-dev-rXXX
Index: src/contributions/resources/generic-exception-handler/src/java/org/wyona/yanel/impl/resources/exception/GenericExceptionHandler.java
===================================================================
--- src/contributions/resources/generic-exception-handler/src/java/org/wyona/yanel/impl/resources/exception/GenericExceptionHandler.java	(revision 0)
+++ src/contributions/resources/generic-exception-handler/src/java/org/wyona/yanel/impl/resources/exception/GenericExceptionHandler.java	(revision 0)
@@ -0,0 +1,44 @@
+/*-
+ * Copyright 2011 Wyona
+ */
+
+package org.wyona.yanel.impl.resources.exception;
+
+import org.wyona.yanel.impl.resources.BasicXMLResource;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import java.lang.Throwable;
+import java.lang.StackTraceElement;
+
+import org.apache.log4j.Logger;
+
+
+/**
+ * A generic exception handler.
+ */
+public class GenericExceptionHandler extends BasicXMLResource {
+    private static Logger log = Logger.getLogger(GenericExceptionHandler.class);
+
+    /**
+     * Generate XML
+     * @param viewid Ignored.
+     * @see org.wyona.yanel.core.Resource
+     */
+    @Override
+    protected InputStream getContentXML(String viewId) {
+        StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+        sb.append("<yanel xmlns=\"http://www.wyona.org/yanel/1.0\">");
+
+        // Request information
+        sb.append("<request servlet-path=\"");
+        sb.append(getPath());
+        sb.append("\" uri=\"");
+        sb.append(getPath());
+        sb.append("\"/>");
+        sb.append("</yanel>");
+
+        return new ByteArrayInputStream(sb.toString().getBytes());
+    }
+}
Index: src/webapp/src/java/org/wyona/yanel/servlet/YanelServlet.java
===================================================================
--- src/webapp/src/java/org/wyona/yanel/servlet/YanelServlet.java	(revision 56190)
+++ src/webapp/src/java/org/wyona/yanel/servlet/YanelServlet.java	(working copy)
@@ -635,12 +636,7 @@
             return;
         } catch (Exception e) {
             log.error(e.getMessage(), e);
-            String message = e.toString() + "\n\n" + getStackTrace(e);
-            //String message = e.toString();
-            Element exceptionElement = (Element) rootElement.appendChild(doc.createElementNS(NAMESPACE, "exception"));
-            exceptionElement.appendChild(doc.createTextNode(message));
-            response.setStatus(javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-            setYanelOutput(request, response, doc);
+            handleException(request, response, e);
             return;
         }
         // END first try
@@ -2257,12 +2267,30 @@
     }
 
     /**
-     *
+     * Handle a generic exception.
+     * @param request The request object.
+     * @param response The reponse object.
+     * @param ex The exception to handle.
      */
-    private String getStackTrace(Exception e) {
-        java.io.StringWriter sw = new java.io.StringWriter();
-        e.printStackTrace(new java.io.PrintWriter(sw));
-        return sw.toString();
+    private void handleException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
+        try {
+            Realm realm = yanelInstance.getMap().getRealm(request.getServletPath());
+            String path = getResource(request, response).getPath();
+            ResourceConfiguration rc = getGlobalResourceConfiguration("generic-exception-handler_yanel-rc.xml", realm);
+            boolean success = generateResponseFromRTview(request, response, rc, path);
+
+            if(!success) {
+                log.error("Generic exception handler is broken!");
+                log.error("Unable to handle the following exception:");
+                log.error(ex, ex);
+            }
+        } catch (Exception e) {
+            log.error("Generic exception handler is broken!");
+            log.error("Unable to handle the following exception:");
+            log.error(ex, ex);
+            log.error("Caught exception while handling the above exception:");
+            log.error(e, e);
+        }
     }
 
     /**
-------------- next part --------------
A non-text attachment was scrubbed...
Name: exception-handler.png
Type: image/png
Size: 36279 bytes
Desc: not available
URL: <http://lists.wyona.org/pipermail/yanel-development/attachments/20110124/d379efc2/attachment-0001.png>


More information about the Yanel-development mailing list