On 12 Jan 2004, at 07:38, Christopher Oliver wrote:


I started looking into how I could get a meaningful stack trace (with location information) spanning (possibly nested) invocations of the sitemap, flowscript, and JXTemplateGenerator. Currently using the JVM stack trace produces a poor result. Although location information is available it isn't provided according to a consistent model. Rhino stores a JS stack trace in a JavaScriptException. JXTemplateGenerator stores its execution stack trace in a sequence of nested SAXParseExceptions. The Sitemap processor currently doesn't seem to produce an execution stack trace, but ProcessingNode's have location information so it should be possible. In addition, javax.xml.transform.TransformerException has location information. o.a.c.ProcessingException gives special treatment to SAXParseException and TransformerException and adds location information to its own stack trace (but only for one level - it doesn't included nested SAXParseException's, for example). There seem to be various other hacks to attempt to include location information in the exception message or stack trace.

The idea is to allow a Cocoon processing element that operates on source code (sitemap, flowscript, jxtemplate, etc...) to provide location information about the execution stack of that processing element when the exception occurred (see also http://marc.theaimsgroup.com/?t=105597249800001&r=1&w=2).

To accomplish this I chose not to use the JVM exception stack trace but instead to store a "Cocoon" stack trace in the current object model. I added the following to the class o.a.c.Cocoon:

public class Cocoon {
   ....
   public interface StackTraceElement {
       public String getComponent();
       public String getMessage();
       public String getMethod();
       public String getURI();
       public int getLineNumber();
       public int getColumnNumber();
   }

public static void addCocoonStackTrace(
Map objectModel,
String message,
String component,
String method,
String uri,
int lineNumber,
int columnNumber);
public static ArrayList /* of StackTraceElement */ getStackTrace(Map objectModel)


}

I added calls to addCocoonStackTrace() in JXTemplateGenerator, FOM_JavaScriptInterpreter, and in MountNode.java and CallNode.java.

With a method like the following:

  private static void dumpStackTrace(Map objectModel) {
       ArrayList stackTrace = Cocoon.getStackTrace(objectModel);
       for (int i = 0, len = stackTrace.size(); i < len; i++) {
           StackTraceElement e = (StackTraceElement)stackTrace.get(i);
           String component = e.getComponent();
           String message = e.getMessage();
           String method = e.getMethod();
           String uri = e.getURI();
           int lineNum = e.getLineNumber();
           int colNum = e.getColumnNumber();
           String out = component + ": ";
           if (message != null) {
               out += message;
               out += " ";
           }
           out += "(";
           if (method != null) {
               out += method + " ";
           }
           out += "at " + uri;
           if (lineNum > 0) {
               out += ", Line " + lineNum;
               if (colNum >= 0) {
                   out += "." + colNum;
               }
           }
           out += ")";
           System.out.println(out);
       }
   }

I was able to produce the following output:

jxtemplate: No pointer for xpath: $blah (at file:/C:/cocoon4/build/webapp/samples/flow/jxcalc/screens/ getNumberA.xml, Line 26.13)
sitemap: (mount at file:/C:/cocoon4/build/webapp/samples/flow/sitemap.xmap:38:68)
sitemap: (mount at file:/C:/cocoon4/build/webapp/samples/sitemap.xmap:154:65)
sitemap: (mount at file:/C:/cocoon4/build/webapp/sitemap.xmap:738:66)
flowscript: (at resource://org/apache/cocoon/components/flow/javascript/fom/ fom_system.js, Line 4)
flowscript: (getNumber at file:/C:/cocoon4/build/webapp/samples/flow/jxcalc/../calc/calc.js, Line 31)
flowscript: (calculator at file:/C:/cocoon4/build/webapp/samples/flow/jxcalc/../calc/calc.js, Line 11)
sitemap: (call at file:/C:/cocoon4/build/webapp/samples/flow/jxcalc/sitemap.xmap:48:42)
sitemap: (mount at file:/C:/cocoon4/build/webapp/samples/flow/sitemap.xmap:38:68)
sitemap: (mount at file:/C:/cocoon4/build/webapp/samples/sitemap.xmap:154:65)
sitemap: (mount at file:/C:/cocoon4/build/webapp/sitemap.xmap:738:66)


It seems straightforward to hook this into Cocoon's error reporter.

WDYT?

I love it!


did I mention you are my hero? ;-)

--
Stefano.



Reply via email to