cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Bart Guijt" <b.gui...@chello.nl>
Subject Re: [RT] [Cocoon 2.2] Stacktraces in context
Date Sun, 22 Jun 2003 12:49:27 GMT
From: "Sylvain Wallez" <sylvain.wallez@anyware-tech.com>
> Bart Guijt wrote:

<snip>

> >What about a stacktrace like this:
> >
> >Error <foo bar> occurred at:
> >Java: org.apache.cocoon.components.SomeComponent.Configure:237:4
> >    Sitemap: /test/sitemap.xmap:25 (map:generate src="..."
> >type="SomeComponent")
> >    Sitemap: /test/sitemap.xmap:24 (map:match pattern="someresource")
> >    Sitemap: /sitemap.xmap:20 (map:mount check-reload="yes" src="{1}/"
> >uri-prefix="{1}" - {1}="test")
> >    Sitemap: /sitemap.xmap:19 (map:match pattern="*/**")
> >    URI: cocoon://test/someresource
> >    XSLT: /xsl/foo-bar.xslt:454:53 (document())
> >    XSLT: /xsl/foo-bar.xslt:25:10 (template: /)
> >    Sitemap: /sitemap.xmap:30 (map:transform src="xsl/foo-bar.xslt")
> >    Sitemap: /sitemap.xmap:28 (map:match pattern="page.html")
> >    URI: page.html

<snip>

> For the treeprocessor, we have to distinguish the two phases of request
> handling :
> - pipeline building (matchers, selectors, actions) : this is under
> control of the treeprocessor, which could log the location of the error
> in the sitemap.
> - pipeline execution (generator, transformer, serializer) : this is more
> difficult because of the streamed nature of the processing.
>
> Something which could help for both phases is to add the sitemap
> statement location in the parameters. This would allow any component to
> know the location of its invocation and reports it in its exception.
>
> Exceptions raised in the second phase out of control of sitemap
> components (e.g. in an XSLT processor) are much more difficult to
> handle. We could have a special implementation of the pipeline that
> shields each element of the pipeline by exception handlers that log the
> error with its location (I whish we still had SAXConnectors...).

Would it be best for all components involved to have a TraceEnabled-like
interface which enables each Cocoon component to send trace events to a
listener? This listener keeps track of the calltrace, which is passed to the
ErrorHandler as an object which in turn is used to generated the appropriate
SAX events for the ErrorGenerator.

The TraceEnabled interface looks something like this (much like LogEnabled):

interface TraceEnabled {
    void enableTracing(Tracer t);
}

The Tracer role looks like this:

interface Tracer {
    String ROLE = "org.apache.cocoon.tracing.Tracer";

    /**
     * Starts a trace event.
     * The event is pushed on the internal Stack.
     */
    void start(String filename, int line, String what);

    /**
     * This is similar to the pop() of a Stack collection:
     * removes the latest trace event from the stack.
     */
    void end();

    /**
     * Returns the depth of trace events we're in.
     */
    int depth();
}

Explanation:

Each registered Cocoon component managed by the CocoonComponentManager might
be TraceEnabled. The CCM initializes those components with a certain Tracer
component which registers all trace events during a request cycle.

The start() and end() methods ensure the top -> bottom path to the current
operation in the process. It is *very important* that each TraceEnabled
component fires 'well-formed' events to create a correct trace! The depth()
method is added to ensure this well-formedness: The TreeProcessor would be
able to check this. Not sure whether it is better to move this to a specific
impl.

I am als not sure what to feed the start() method. It is clear it needs some
context to be useful, but the context is different for different components:
- In the treeprocessor, one would trace matchers, actions/selectors,
generators/transformers/serializers with their linenumbers;
- in an XSLT process, one would register named/matched templates,
document()/include/import/DTD includes with their linenumbers;
- in case of URI's, one would register the uri;
- in case of (user-written) Java components, one would register the method
(and probably not linenumbers if we can't use some compiler preprocessor!)

The trade-off is ease-of-use (just filename, linenumber and a context
string) and fine-grained, conplete specification (more
classes/interfaces/initializations; complexity).

A DefaultTracerImpl might add methods to get the complete trace, to output
SAX events and/or to output a String representation of the trace.


-- XSLT trace events: --

The difficulty is having XSLT processors report the templates which are
processed, if necessary. Fortunately, Xalan (and I guess XSLTC) and maybe
SAXON do have a tracing feature. One would be able to build an
adapter/listener to catch these events in a Tracer component. Unfortunately,
specific XsltTransformer components are needed for different XSLT
processors. Need to dig into this to find out what and how.


-- Cocoon debugging: --

Using a Tracer component doesn't only enable semantically sufficient
Stacktraces, it also enables Cocoon Debugging! A full-fledged Cocoon IDE
can't do without it! (OK, is there some space left on cvs.apache.org? ;-)


What do you all think about this?


Cheers,
Bart Guijt


Mime
View raw message