You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Jeremy Quinn <je...@apache.org> on 2006/03/16 19:00:59 UTC

error handling in aggregations

Hi All

I am working on a project that uses a lot of aggregations in the  
sitemap, using <map:aggregate>.

My aggregated parts all call cocoon:// pipelines in other subsitemap,  
via the top level sitemap, where my top-level sitemap is not the one  
that comes built-in with Cocoon, but is my own, mounted directly from  
cocoon.xconf (this does not seem to make any difference).

I have one top-level <map:handle-errors>.

When an exception occurs in one of the aggregate parts eg.  
o.a.e.s.SourceException, this is what appears to happen :
	the outer pipeline carries on regardless, producing normal content  
(just missing that part)
	the error-handler outputs it's content

Result : two consecutive <html/> pages in one request !!

I have tried every combination I can think of, in terms of the  
placement of other <map:handle-errors>s in the other subsitemaps, or  
their pipelines. All result in multiple html pages in one request.

I am working around this by having a <map:handle-errors> that outputs  
the simplest possible html '<br/>', which gets added after the  
closing </html> tag of my page, but does not seem to cause problems  
in the browser.

I am actually using Cocoon 2.1.7, but I see little difference between  
ContentAggregator.java in either version.

I have either misconfigured my sitemap to cause this behaviour, or  
there are bugs in the aggregator.

What I would expect to happen if an aggregated part throws an  
exception, is that the output of the <map:handle-errors> would  
replace the content of that one failed part.

Has anyone else experienced this problem?


Thanks

regards Jeremy

Re: error handling in aggregations

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Jeremy Quinn wrote:
> Many thanks for the links Vadim !!

You *are* welcome, you know. No need for double exclamation marks ;-P

Vadim


> regards Jeremy
> 
> 
> On 20 Mar 2006, at 18:01, Vadim Gritsenko wrote:
> 
>> Jeremy Quinn wrote:
>>> On 20 Mar 2006, at 12:41, Bruno Dumon wrote:
>>>> On Mon, 2006-03-20 at 12:00 +0000, Jeremy Quinn wrote:
>>>>>
>>>>> Lets say the aggregation part that is in error, is a cocoon://
>>>>> pipeline, it is possible that the called pipeline has it's own local
>>>>> error-handler ..... if this is the case, it could be interesting to
>>>>> see if that one exception could run that one error-handler whose
>>>>> output would replace the output of that one aggregation part, instead
>>>>> of the whole pipeline.
>>>>
>>>> I can imagine this would be useful. Maybe it even works if the called
>>>> pipeline has an error handler with "when='internal'" ?
>>> I had never seen this attribute before, or find any documentation 
>>> .... all I can find is the code ...
>>
>> Vote Thread:
>> http://marc.theaimsgroup.com/?t=111076148700002&r=1
>>
>> Change Log (since changes.html is broken):
>> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111165425228965
>>
>> Samples:
>> http://svn.apache.org/viewcvs.cgi/cocoon/branches/BRANCH_2_1_X/src/webapp/samples/errorhandling/ 
>>
>> Vadim


Re: error handling in aggregations

Posted by Jeremy Quinn <je...@apache.org>.
Many thanks for the links Vadim !!

regards Jeremy


On 20 Mar 2006, at 18:01, Vadim Gritsenko wrote:

> Jeremy Quinn wrote:
>> On 20 Mar 2006, at 12:41, Bruno Dumon wrote:
>>> On Mon, 2006-03-20 at 12:00 +0000, Jeremy Quinn wrote:
>>>>
>>>> Lets say the aggregation part that is in error, is a cocoon://
>>>> pipeline, it is possible that the called pipeline has it's own  
>>>> local
>>>> error-handler ..... if this is the case, it could be interesting to
>>>> see if that one exception could run that one error-handler whose
>>>> output would replace the output of that one aggregation part,  
>>>> instead
>>>> of the whole pipeline.
>>>
>>> I can imagine this would be useful. Maybe it even works if the  
>>> called
>>> pipeline has an error handler with "when='internal'" ?
>> I had never seen this attribute before, or find any  
>> documentation .... all I can find is the code ...
>
> Vote Thread:
> http://marc.theaimsgroup.com/?t=111076148700002&r=1
>
> Change Log (since changes.html is broken):
> http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111165425228965
>
> Samples:
> http://svn.apache.org/viewcvs.cgi/cocoon/branches/BRANCH_2_1_X/src/ 
> webapp/samples/errorhandling/
>
>
> Vadim


Re: error handling in aggregations

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Jeremy Quinn wrote:
> 
> On 20 Mar 2006, at 12:41, Bruno Dumon wrote:
> 
>> On Mon, 2006-03-20 at 12:00 +0000, Jeremy Quinn wrote:
>>>
>>> Lets say the aggregation part that is in error, is a cocoon://
>>> pipeline, it is possible that the called pipeline has it's own local
>>> error-handler ..... if this is the case, it could be interesting to
>>> see if that one exception could run that one error-handler whose
>>> output would replace the output of that one aggregation part, instead
>>> of the whole pipeline.
>>
>> I can imagine this would be useful. Maybe it even works if the called
>> pipeline has an error handler with "when='internal'" ?
> 
> I had never seen this attribute before, or find any documentation .... 
> all I can find is the code ...

Vote Thread:
http://marc.theaimsgroup.com/?t=111076148700002&r=1

Change Log (since changes.html is broken):
http://marc.theaimsgroup.com/?l=xml-cocoon-dev&m=111165425228965

Samples:
http://svn.apache.org/viewcvs.cgi/cocoon/branches/BRANCH_2_1_X/src/webapp/samples/errorhandling/


Vadim

Re: error handling in aggregations

Posted by Jeremy Quinn <je...@apache.org>.
On 20 Mar 2006, at 12:41, Bruno Dumon wrote:

> On Mon, 2006-03-20 at 12:00 +0000, Jeremy Quinn wrote:
>> Thanks for your reply Bruno,
>>
>> On 19 Mar 2006, at 13:32, Bruno Dumon wrote:
>>
>>> On Sun, 2006-03-19 at 12:10 +0000, Jeremy Quinn wrote:
>>>> Hi All
>>>>
>>>> Investigating this further, I came up with this simplest possible
>>>> sitemap to reproduce the problem :
>>>>
>>>> <?xml version="1.0"?>
>>>> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
>>>>
>>>>    <map:components>
>>>>      <map:generators default="file">
>>>>        <map:generator name="file" label="content"
>>>> logger="sitemap.generator.file" pool-grow="4" pool-max="32" pool-
>>>> min="4" src="org.apache.cocoon.generation.FileGenerator"/>
>>>>     </map:generators>
>>>>      <map:serializers default="xml">
>>>>        <map:serializer name="xml" logger="sitemap.serializer.xml"
>>>> mime-type="text/xml" pool-grow="4" pool-max="32" pool-min="4"
>>>> src="org.apache.cocoon.serialization.XMLSerializer"/>
>>>>      </map:serializers>
>>>>      <map:matchers default="wildcard">
>>>>        <map:matcher logger="sitemap.matcher.wildcard"  
>>>> name="wildcard"
>>>> src="org.apache.cocoon.matching.WildcardURIMatcher"/>
>>>>      </map:matchers>
>>>>      <map:pipes default="noncaching">
>>>>        <map:pipe logger="sitemap.pipes.noncaching"  
>>>> name="noncaching"
>>>> src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessin 
>>>> gP
>>>> ipe
>>>> line">
>>>>          <parameter name="outputBufferSize" value="32768"/>
>>>>        </map:pipe>
>>>>      </map:pipes>
>>>>    </map:components>
>>>>
>>>>    <map:pipelines>
>>>>
>>>>      <map:pipeline internal-only="false" type="noncaching">
>>>>
>>>>        <map:match pattern="test">
>>>>          <map:aggregate element="site">
>>>>            <map:part element="content1" src="nothing.xml"/>
>>>>            <map:part element="content2" src="nothingelse.xml"/>
>>>>          </map:aggregate>
>>>>          <map:serialize type="xml" />
>>>>        </map:match>
>>>>
>>>>      </map:pipeline>
>>>>
>>>>    </map:pipelines>
>>>>
>>>> </map:sitemap>
>>>>
>>>> I set this up as the top-level sitemap, loaded by cocoon.xconf.
>>>>
>>>> I access the url and I get this :
>>>>
>>>> $ curl http://localhost:8888/test
>>>> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></
>>>> site><html><head><title>Resource Not Found</title><style><!--body
>>>> { background-color: white; color: black; font-family: verdana,
>>>> helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px  
>>>> 0px;
>>>> border-width: 0px 0px 1px 0px; border-style: solid; border-color:
>>>> #336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px;
>>>> border-style: solid; border-color: #336699; }span {color: #336699;}
>>>> pre {padding-left: 20px;}a:link {font-weight: bold; color:  
>>>> #336699;}
>>>> a:visited {color: #336699; }a:hover {color: #800000; background-
>>>> color: #ffff80;}a:active {color: #006666;}--></style></
>>>> head><body><h1>Resource Not Found</h1><p><span>Message:</span>
>>>> Resource Not Found</p><p><span>Description:</span> The requested
>>>> resource &quot;/test&quot; could not be found</p><p><span>Sender:</
>>>> span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</
>>>> span> Cocoon Servlet</p><p class='footer'><a href='http://
>>>> cocoon.apache.org/'>Apache Cocoon 2.1.9-dev</p></body></html>
>>>>
>>>> Two outputs ....
>>>>
>>>> First the content of the failed aggregation : <site><content1/></
>>>> site>
>>>> Then the generic error message.
>>>>
>>>>
>>>> If I now comment out the line "<parameter name="outputBufferSize"
>>>> value="32768"/>" from the <map:pipe>. then I only get the error
>>>> message.
>>>>
>>>> I have tested this in 2.1.7 --> 2.1.9-dev.
>>>>
>>>> I suspect this did not occur in 2.1.6.
>>>>
>>>>
>>>> Is this a bug, or is it what I should expect to happen if an output
>>>> buffer is configured?
>>>
>>> Hi Jeremy,
>>>
>>> Given the streaming nature of the SAX pipeline, buffering the  
>>> complete
>>> output at the end of the pipeline is indeed the only way to reliably
>>> recover from exceptions that might happen during its execution.
>>> This is
>>> not necessarily bad, as whatever other way you would solve this, you
>>> would need to temporarily store the data in one way or another to be
>>> able to recover from errors.
>>
>> Thanks for your explanation.
>>
>> So I wonder why is this behaviour is 'fixed' when I turn off the  
>> buffer?
>> Or am I not actually turning off the buffer by removing that
>> parameter, just allowing it to be set to a different default value?
>
> Yes, by default the whole output is buffered before sending it to the
> client. If you search for outputBufferSize in Cocoon's default root
> sitemap you will find some information on this.
>

Ah !! So by removing that parameter, you are not turning the buffer  
off, you are setting it to unlimited size.

>>
>>> There's a little bit more to it though. In case of an error the  
>>> output
>>> your pipeline is quite small:
>>>
>>> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></site>
>>
>> It is not normally that small, in my 'real' pipelines, there is far
>> more content.
>>
>>> which is much less then your buffer size of 32768, so normally  
>>> Cocoon
>>> should still be able to reset the output before generating the error
>>> page.
>>>
>>> Someone asked the exact same question a week or two ago on the users
>>> list, at which time I had a quick look into this. The cause is that
>>> the
>>> ContentAggregator class, which does the aggregation, will still
>>> generate
>>> the endDocument event in case an exception occurs. IMO, it should
>>> not do
>>> this (unless it would also catch the exception). Here is the  
>>> relevant
>>> fragment:
>>>
>>>
>>>                 try {
>>>                     SourceUtil.parse(this.manager, part.source,  
>>> this);
>>>                 } finally {
>>>                     if (part.element != null) {
>>>                         endElem(part.element);
>>>                     }
>>>                 }
>>>             }
>>>         } finally {
>>>             endElem(this.rootElement);
>>>             this.contentHandler.endDocument();
>>>         }
>>>
>>>
>>> I'd be in favor of removing these two finally blocks.
>>
>> OK.
>>
>> I suppose there is another possible option for what happens when an
>> exception is thrown in an aggregation ....
>>
>> ATM, I think what is supposed to happen is that if an aggregation in
>> a pipleine throws an exception, the output of one error handler
>> should replace the whole output of that pipeline.
>>
>> Lets say the aggregation part that is in error, is a cocoon://
>> pipeline, it is possible that the called pipeline has it's own local
>> error-handler ..... if this is the case, it could be interesting to
>> see if that one exception could run that one error-handler whose
>> output would replace the output of that one aggregation part, instead
>> of the whole pipeline.
>>
>> WDYT?
>
> I can imagine this would be useful. Maybe it even works if the called
> pipeline has an error handler with "when='internal'" ?

I had never seen this attribute before, or find any  
documentation .... all I can find is the code ...

I will test this asap.

Many thanks for the pointer.

regards Jeremy

Re: error handling in aggregations

Posted by Bruno Dumon <br...@outerthought.org>.
On Mon, 2006-03-20 at 12:00 +0000, Jeremy Quinn wrote:
> Thanks for your reply Bruno,
> 
> On 19 Mar 2006, at 13:32, Bruno Dumon wrote:
> 
> > On Sun, 2006-03-19 at 12:10 +0000, Jeremy Quinn wrote:
> >> Hi All
> >>
> >> Investigating this further, I came up with this simplest possible
> >> sitemap to reproduce the problem :
> >>
> >> <?xml version="1.0"?>
> >> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
> >>
> >>    <map:components>
> >>      <map:generators default="file">
> >>        <map:generator name="file" label="content"
> >> logger="sitemap.generator.file" pool-grow="4" pool-max="32" pool-
> >> min="4" src="org.apache.cocoon.generation.FileGenerator"/>
> >>     </map:generators>
> >>      <map:serializers default="xml">
> >>        <map:serializer name="xml" logger="sitemap.serializer.xml"
> >> mime-type="text/xml" pool-grow="4" pool-max="32" pool-min="4"
> >> src="org.apache.cocoon.serialization.XMLSerializer"/>
> >>      </map:serializers>
> >>      <map:matchers default="wildcard">
> >>        <map:matcher logger="sitemap.matcher.wildcard" name="wildcard"
> >> src="org.apache.cocoon.matching.WildcardURIMatcher"/>
> >>      </map:matchers>
> >>      <map:pipes default="noncaching">
> >>        <map:pipe logger="sitemap.pipes.noncaching" name="noncaching"
> >> src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingP 
> >> ipe
> >> line">
> >>          <parameter name="outputBufferSize" value="32768"/>
> >>        </map:pipe>
> >>      </map:pipes>
> >>    </map:components>
> >>
> >>    <map:pipelines>
> >>
> >>      <map:pipeline internal-only="false" type="noncaching">
> >>
> >>        <map:match pattern="test">
> >>          <map:aggregate element="site">
> >>            <map:part element="content1" src="nothing.xml"/>
> >>            <map:part element="content2" src="nothingelse.xml"/>
> >>          </map:aggregate>
> >>          <map:serialize type="xml" />
> >>        </map:match>
> >>
> >>      </map:pipeline>
> >>
> >>    </map:pipelines>
> >>
> >> </map:sitemap>
> >>
> >> I set this up as the top-level sitemap, loaded by cocoon.xconf.
> >>
> >> I access the url and I get this :
> >>
> >> $ curl http://localhost:8888/test
> >> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></
> >> site><html><head><title>Resource Not Found</title><style><!--body
> >> { background-color: white; color: black; font-family: verdana,
> >> helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px 0px;
> >> border-width: 0px 0px 1px 0px; border-style: solid; border-color:
> >> #336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px;
> >> border-style: solid; border-color: #336699; }span {color: #336699;}
> >> pre {padding-left: 20px;}a:link {font-weight: bold; color: #336699;}
> >> a:visited {color: #336699; }a:hover {color: #800000; background-
> >> color: #ffff80;}a:active {color: #006666;}--></style></
> >> head><body><h1>Resource Not Found</h1><p><span>Message:</span>
> >> Resource Not Found</p><p><span>Description:</span> The requested
> >> resource &quot;/test&quot; could not be found</p><p><span>Sender:</
> >> span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</
> >> span> Cocoon Servlet</p><p class='footer'><a href='http://
> >> cocoon.apache.org/'>Apache Cocoon 2.1.9-dev</p></body></html>
> >>
> >> Two outputs ....
> >>
> >> First the content of the failed aggregation : <site><content1/></ 
> >> site>
> >> Then the generic error message.
> >>
> >>
> >> If I now comment out the line "<parameter name="outputBufferSize"
> >> value="32768"/>" from the <map:pipe>. then I only get the error  
> >> message.
> >>
> >> I have tested this in 2.1.7 --> 2.1.9-dev.
> >>
> >> I suspect this did not occur in 2.1.6.
> >>
> >>
> >> Is this a bug, or is it what I should expect to happen if an output
> >> buffer is configured?
> >
> > Hi Jeremy,
> >
> > Given the streaming nature of the SAX pipeline, buffering the complete
> > output at the end of the pipeline is indeed the only way to reliably
> > recover from exceptions that might happen during its execution.  
> > This is
> > not necessarily bad, as whatever other way you would solve this, you
> > would need to temporarily store the data in one way or another to be
> > able to recover from errors.
> 
> Thanks for your explanation.
> 
> So I wonder why is this behaviour is 'fixed' when I turn off the buffer?
> Or am I not actually turning off the buffer by removing that  
> parameter, just allowing it to be set to a different default value?

Yes, by default the whole output is buffered before sending it to the
client. If you search for outputBufferSize in Cocoon's default root
sitemap you will find some information on this.

> 
> > There's a little bit more to it though. In case of an error the output
> > your pipeline is quite small:
> >
> > <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></site>
> 
> It is not normally that small, in my 'real' pipelines, there is far  
> more content.
> 
> > which is much less then your buffer size of 32768, so normally Cocoon
> > should still be able to reset the output before generating the error
> > page.
> >
> > Someone asked the exact same question a week or two ago on the users
> > list, at which time I had a quick look into this. The cause is that  
> > the
> > ContentAggregator class, which does the aggregation, will still  
> > generate
> > the endDocument event in case an exception occurs. IMO, it should  
> > not do
> > this (unless it would also catch the exception). Here is the relevant
> > fragment:
> >
> >
> >                 try {
> >                     SourceUtil.parse(this.manager, part.source, this);
> >                 } finally {
> >                     if (part.element != null) {
> >                         endElem(part.element);
> >                     }
> >                 }
> >             }
> >         } finally {
> >             endElem(this.rootElement);
> >             this.contentHandler.endDocument();
> >         }
> >
> >
> > I'd be in favor of removing these two finally blocks.
> 
> OK.
> 
> I suppose there is another possible option for what happens when an  
> exception is thrown in an aggregation ....
> 
> ATM, I think what is supposed to happen is that if an aggregation in  
> a pipleine throws an exception, the output of one error handler  
> should replace the whole output of that pipeline.
> 
> Lets say the aggregation part that is in error, is a cocoon://  
> pipeline, it is possible that the called pipeline has it's own local  
> error-handler ..... if this is the case, it could be interesting to  
> see if that one exception could run that one error-handler whose  
> output would replace the output of that one aggregation part, instead  
> of the whole pipeline.
> 
> WDYT?

I can imagine this would be useful. Maybe it even works if the called
pipeline has an error handler with "when='internal'" ?

-- 
Bruno Dumon                             http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
bruno@outerthought.org                          bruno@apache.org


Re: error handling in aggregations

Posted by Jeremy Quinn <je...@apache.org>.
Thanks for your reply Bruno,

On 19 Mar 2006, at 13:32, Bruno Dumon wrote:

> On Sun, 2006-03-19 at 12:10 +0000, Jeremy Quinn wrote:
>> Hi All
>>
>> Investigating this further, I came up with this simplest possible
>> sitemap to reproduce the problem :
>>
>> <?xml version="1.0"?>
>> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
>>
>>    <map:components>
>>      <map:generators default="file">
>>        <map:generator name="file" label="content"
>> logger="sitemap.generator.file" pool-grow="4" pool-max="32" pool-
>> min="4" src="org.apache.cocoon.generation.FileGenerator"/>
>>     </map:generators>
>>      <map:serializers default="xml">
>>        <map:serializer name="xml" logger="sitemap.serializer.xml"
>> mime-type="text/xml" pool-grow="4" pool-max="32" pool-min="4"
>> src="org.apache.cocoon.serialization.XMLSerializer"/>
>>      </map:serializers>
>>      <map:matchers default="wildcard">
>>        <map:matcher logger="sitemap.matcher.wildcard" name="wildcard"
>> src="org.apache.cocoon.matching.WildcardURIMatcher"/>
>>      </map:matchers>
>>      <map:pipes default="noncaching">
>>        <map:pipe logger="sitemap.pipes.noncaching" name="noncaching"
>> src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingP 
>> ipe
>> line">
>>          <parameter name="outputBufferSize" value="32768"/>
>>        </map:pipe>
>>      </map:pipes>
>>    </map:components>
>>
>>    <map:pipelines>
>>
>>      <map:pipeline internal-only="false" type="noncaching">
>>
>>        <map:match pattern="test">
>>          <map:aggregate element="site">
>>            <map:part element="content1" src="nothing.xml"/>
>>            <map:part element="content2" src="nothingelse.xml"/>
>>          </map:aggregate>
>>          <map:serialize type="xml" />
>>        </map:match>
>>
>>      </map:pipeline>
>>
>>    </map:pipelines>
>>
>> </map:sitemap>
>>
>> I set this up as the top-level sitemap, loaded by cocoon.xconf.
>>
>> I access the url and I get this :
>>
>> $ curl http://localhost:8888/test
>> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></
>> site><html><head><title>Resource Not Found</title><style><!--body
>> { background-color: white; color: black; font-family: verdana,
>> helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px 0px;
>> border-width: 0px 0px 1px 0px; border-style: solid; border-color:
>> #336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px;
>> border-style: solid; border-color: #336699; }span {color: #336699;}
>> pre {padding-left: 20px;}a:link {font-weight: bold; color: #336699;}
>> a:visited {color: #336699; }a:hover {color: #800000; background-
>> color: #ffff80;}a:active {color: #006666;}--></style></
>> head><body><h1>Resource Not Found</h1><p><span>Message:</span>
>> Resource Not Found</p><p><span>Description:</span> The requested
>> resource &quot;/test&quot; could not be found</p><p><span>Sender:</
>> span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</
>> span> Cocoon Servlet</p><p class='footer'><a href='http://
>> cocoon.apache.org/'>Apache Cocoon 2.1.9-dev</p></body></html>
>>
>> Two outputs ....
>>
>> First the content of the failed aggregation : <site><content1/></ 
>> site>
>> Then the generic error message.
>>
>>
>> If I now comment out the line "<parameter name="outputBufferSize"
>> value="32768"/>" from the <map:pipe>. then I only get the error  
>> message.
>>
>> I have tested this in 2.1.7 --> 2.1.9-dev.
>>
>> I suspect this did not occur in 2.1.6.
>>
>>
>> Is this a bug, or is it what I should expect to happen if an output
>> buffer is configured?
>
> Hi Jeremy,
>
> Given the streaming nature of the SAX pipeline, buffering the complete
> output at the end of the pipeline is indeed the only way to reliably
> recover from exceptions that might happen during its execution.  
> This is
> not necessarily bad, as whatever other way you would solve this, you
> would need to temporarily store the data in one way or another to be
> able to recover from errors.

Thanks for your explanation.

So I wonder why is this behaviour is 'fixed' when I turn off the buffer?
Or am I not actually turning off the buffer by removing that  
parameter, just allowing it to be set to a different default value?

> There's a little bit more to it though. In case of an error the output
> your pipeline is quite small:
>
> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></site>

It is not normally that small, in my 'real' pipelines, there is far  
more content.

> which is much less then your buffer size of 32768, so normally Cocoon
> should still be able to reset the output before generating the error
> page.
>
> Someone asked the exact same question a week or two ago on the users
> list, at which time I had a quick look into this. The cause is that  
> the
> ContentAggregator class, which does the aggregation, will still  
> generate
> the endDocument event in case an exception occurs. IMO, it should  
> not do
> this (unless it would also catch the exception). Here is the relevant
> fragment:
>
>
>                 try {
>                     SourceUtil.parse(this.manager, part.source, this);
>                 } finally {
>                     if (part.element != null) {
>                         endElem(part.element);
>                     }
>                 }
>             }
>         } finally {
>             endElem(this.rootElement);
>             this.contentHandler.endDocument();
>         }
>
>
> I'd be in favor of removing these two finally blocks.

OK.

I suppose there is another possible option for what happens when an  
exception is thrown in an aggregation ....

ATM, I think what is supposed to happen is that if an aggregation in  
a pipleine throws an exception, the output of one error handler  
should replace the whole output of that pipeline.

Lets say the aggregation part that is in error, is a cocoon://  
pipeline, it is possible that the called pipeline has it's own local  
error-handler ..... if this is the case, it could be interesting to  
see if that one exception could run that one error-handler whose  
output would replace the output of that one aggregation part, instead  
of the whole pipeline.

WDYT?

regards Jeremy


Re: error handling in aggregations

Posted by Bruno Dumon <br...@outerthought.org>.
On Sun, 2006-03-19 at 12:10 +0000, Jeremy Quinn wrote:
> Hi All
> 
> Investigating this further, I came up with this simplest possible  
> sitemap to reproduce the problem :
> 
> <?xml version="1.0"?>
> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">
> 
>    <map:components>
>      <map:generators default="file">
>        <map:generator name="file" label="content"  
> logger="sitemap.generator.file" pool-grow="4" pool-max="32" pool- 
> min="4" src="org.apache.cocoon.generation.FileGenerator"/>
>     </map:generators>
>      <map:serializers default="xml">
>        <map:serializer name="xml" logger="sitemap.serializer.xml"  
> mime-type="text/xml" pool-grow="4" pool-max="32" pool-min="4"  
> src="org.apache.cocoon.serialization.XMLSerializer"/>
>      </map:serializers>
>      <map:matchers default="wildcard">
>        <map:matcher logger="sitemap.matcher.wildcard" name="wildcard"  
> src="org.apache.cocoon.matching.WildcardURIMatcher"/>
>      </map:matchers>
>      <map:pipes default="noncaching">
>        <map:pipe logger="sitemap.pipes.noncaching" name="noncaching"  
> src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipe 
> line">
>          <parameter name="outputBufferSize" value="32768"/>
>        </map:pipe>
>      </map:pipes>
>    </map:components>
> 
>    <map:pipelines>
> 
>      <map:pipeline internal-only="false" type="noncaching">
> 
>        <map:match pattern="test">
>          <map:aggregate element="site">
>            <map:part element="content1" src="nothing.xml"/>
>            <map:part element="content2" src="nothingelse.xml"/>
>          </map:aggregate>
>          <map:serialize type="xml" />
>        </map:match>
> 
>      </map:pipeline>
> 
>    </map:pipelines>
> 
> </map:sitemap>
> 
> I set this up as the top-level sitemap, loaded by cocoon.xconf.
> 
> I access the url and I get this :
> 
> $ curl http://localhost:8888/test
> <?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></ 
> site><html><head><title>Resource Not Found</title><style><!--body  
> { background-color: white; color: black; font-family: verdana,  
> helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px 0px;  
> border-width: 0px 0px 1px 0px; border-style: solid; border-color:  
> #336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px;  
> border-style: solid; border-color: #336699; }span {color: #336699;} 
> pre {padding-left: 20px;}a:link {font-weight: bold; color: #336699;} 
> a:visited {color: #336699; }a:hover {color: #800000; background- 
> color: #ffff80;}a:active {color: #006666;}--></style></ 
> head><body><h1>Resource Not Found</h1><p><span>Message:</span>  
> Resource Not Found</p><p><span>Description:</span> The requested  
> resource &quot;/test&quot; could not be found</p><p><span>Sender:</ 
> span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</ 
> span> Cocoon Servlet</p><p class='footer'><a href='http:// 
> cocoon.apache.org/'>Apache Cocoon 2.1.9-dev</p></body></html>
> 
> Two outputs ....
> 
> First the content of the failed aggregation : <site><content1/></site>
> Then the generic error message.
> 
> 
> If I now comment out the line "<parameter name="outputBufferSize"  
> value="32768"/>" from the <map:pipe>. then I only get the error message.
> 
> I have tested this in 2.1.7 --> 2.1.9-dev.
> 
> I suspect this did not occur in 2.1.6.
> 
> 
> Is this a bug, or is it what I should expect to happen if an output  
> buffer is configured?

Hi Jeremy,

Given the streaming nature of the SAX pipeline, buffering the complete
output at the end of the pipeline is indeed the only way to reliably
recover from exceptions that might happen during its execution. This is
not necessarily bad, as whatever other way you would solve this, you
would need to temporarily store the data in one way or another to be
able to recover from errors.

There's a little bit more to it though. In case of an error the output
your pipeline is quite small:

<?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></site>

which is much less then your buffer size of 32768, so normally Cocoon
should still be able to reset the output before generating the error
page.

Someone asked the exact same question a week or two ago on the users
list, at which time I had a quick look into this. The cause is that the
ContentAggregator class, which does the aggregation, will still generate
the endDocument event in case an exception occurs. IMO, it should not do
this (unless it would also catch the exception). Here is the relevant
fragment:


                try {
                    SourceUtil.parse(this.manager, part.source, this);
                } finally {
                    if (part.element != null) {
                        endElem(part.element);
                    }
                }
            }
        } finally {
            endElem(this.rootElement);
            this.contentHandler.endDocument();
        }


I'd be in favor of removing these two finally blocks.

-- 
Bruno Dumon                             http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
bruno@outerthought.org                          bruno@apache.org


Re: error handling in aggregations

Posted by Jeremy Quinn <je...@apache.org>.
Hi All

Investigating this further, I came up with this simplest possible  
sitemap to reproduce the problem :

<?xml version="1.0"?>
<map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0">

   <map:components>
     <map:generators default="file">
       <map:generator name="file" label="content"  
logger="sitemap.generator.file" pool-grow="4" pool-max="32" pool- 
min="4" src="org.apache.cocoon.generation.FileGenerator"/>
    </map:generators>
     <map:serializers default="xml">
       <map:serializer name="xml" logger="sitemap.serializer.xml"  
mime-type="text/xml" pool-grow="4" pool-max="32" pool-min="4"  
src="org.apache.cocoon.serialization.XMLSerializer"/>
     </map:serializers>
     <map:matchers default="wildcard">
       <map:matcher logger="sitemap.matcher.wildcard" name="wildcard"  
src="org.apache.cocoon.matching.WildcardURIMatcher"/>
     </map:matchers>
     <map:pipes default="noncaching">
       <map:pipe logger="sitemap.pipes.noncaching" name="noncaching"  
src="org.apache.cocoon.components.pipeline.impl.NonCachingProcessingPipe 
line">
         <parameter name="outputBufferSize" value="32768"/>
       </map:pipe>
     </map:pipes>
   </map:components>

   <map:pipelines>

     <map:pipeline internal-only="false" type="noncaching">

       <map:match pattern="test">
         <map:aggregate element="site">
           <map:part element="content1" src="nothing.xml"/>
           <map:part element="content2" src="nothingelse.xml"/>
         </map:aggregate>
         <map:serialize type="xml" />
       </map:match>

     </map:pipeline>

   </map:pipelines>

</map:sitemap>

I set this up as the top-level sitemap, loaded by cocoon.xconf.

I access the url and I get this :

$ curl http://localhost:8888/test
<?xml version="1.0" encoding="ISO-8859-1"?><site><content1/></ 
site><html><head><title>Resource Not Found</title><style><!--body  
{ background-color: white; color: black; font-family: verdana,  
helvetica, sanf serif;}h1 {color: #336699; margin: 0px 0px 20px 0px;  
border-width: 0px 0px 1px 0px; border-style: solid; border-color:  
#336699;}p.footer { color: #336699; border-width: 1px 0px 0px 0px;  
border-style: solid; border-color: #336699; }span {color: #336699;} 
pre {padding-left: 20px;}a:link {font-weight: bold; color: #336699;} 
a:visited {color: #336699; }a:hover {color: #800000; background- 
color: #ffff80;}a:active {color: #006666;}--></style></ 
head><body><h1>Resource Not Found</h1><p><span>Message:</span>  
Resource Not Found</p><p><span>Description:</span> The requested  
resource &quot;/test&quot; could not be found</p><p><span>Sender:</ 
span> org.apache.cocoon.servlet.CocoonServlet</p><p><span>Source:</ 
span> Cocoon Servlet</p><p class='footer'><a href='http:// 
cocoon.apache.org/'>Apache Cocoon 2.1.9-dev</p></body></html>

Two outputs ....

First the content of the failed aggregation : <site><content1/></site>
Then the generic error message.


If I now comment out the line "<parameter name="outputBufferSize"  
value="32768"/>" from the <map:pipe>. then I only get the error message.

I have tested this in 2.1.7 --> 2.1.9-dev.

I suspect this did not occur in 2.1.6.


Is this a bug, or is it what I should expect to happen if an output  
buffer is configured?


Thanks

regards Jeremy


On 16 Mar 2006, at 18:00, Jeremy Quinn wrote:

> Hi All
>
> I am working on a project that uses a lot of aggregations in the  
> sitemap, using <map:aggregate>.
>
> My aggregated parts all call cocoon:// pipelines in other  
> subsitemap, via the top level sitemap, where my top-level sitemap  
> is not the one that comes built-in with Cocoon, but is my own,  
> mounted directly from cocoon.xconf (this does not seem to make any  
> difference).
>
> I have one top-level <map:handle-errors>.
>
> When an exception occurs in one of the aggregate parts eg.  
> o.a.e.s.SourceException, this is what appears to happen :
> 	the outer pipeline carries on regardless, producing normal content  
> (just missing that part)
> 	the error-handler outputs it's content
>
> Result : two consecutive <html/> pages in one request !!
>
> I have tried every combination I can think of, in terms of the  
> placement of other <map:handle-errors>s in the other subsitemaps,  
> or their pipelines. All result in multiple html pages in one request.
>
> I am working around this by having a <map:handle-errors> that  
> outputs the simplest possible html '<br/>', which gets added after  
> the closing </html> tag of my page, but does not seem to cause  
> problems in the browser.
>
> I am actually using Cocoon 2.1.7, but I see little difference  
> between ContentAggregator.java in either version.
>
> I have either misconfigured my sitemap to cause this behaviour, or  
> there are bugs in the aggregator.
>
> What I would expect to happen if an aggregated part throws an  
> exception, is that the output of the <map:handle-errors> would  
> replace the content of that one failed part.
>
> Has anyone else experienced this problem?
>
>
> Thanks
>
> regards Jeremy