John W. Long wrote:
> Jay Levitt wrote:
>> Jay Levitt wrote:
>>> I understand the intent, but I wonder if there's a less intrusive way to
>>> accomplish it, while still allowing outer tags to rescue their own
>>> exceptions. What if that rescue were executed only on the outermost
>>> tags? Would that break anything?
>> I've submitted a patch that accomplishes this - ticket #177.
>
> This sounds like a useful idea. Can you post some code which
> demonstrates why this would be useful? Also I'll need unit tests before
> this can be applied to the core.
Argh! This is harder than it seemed. In my version, when
PageContext::render_tag reraises the exception, the parent tag rescues
it, of course - which means the parent tag never finishes what it's
doing. So anything inside the parent tag following the exception is
lost. Oops.
I imagine if I understood continuations better, I'd know how to code
this; the inner tag should raise an exception, and the outer tag should
note that, continue its processing, and then, at the end, reraise or
render. Sadly, I'm too new to Ruby, and non-procedural languages in
general, to know how to do that.
If anyone else wants to take a crack at this, here's how far I got.. I'm
about to go read a bunch of "continuations made easy" articles.
-----
def render_tag(name, attributes = {}, &block)
super
rescue Exception => e
nesting = current_nesting
@tag_binding_stack.pop
if reraise_exception(nesting, name, e)
p @page.behavior.parser
raise e
else
render_error_message(e.message)
end
end
..
def reraise_exception(nesting, name, e)
tag_pos = nesting.rindex(name)
# Missing end tag
return false if tag_pos.nil?
# Let inner tags pass exceptions to outer tags.
return true if tag_pos > 1
# Let bugs report themselves to unit tests.
return true if RAILS_ENV == "test" and not e.is_a?(TagError)
false
end
_______________________________________________
Radiant mailing list
[email protected]
http://lists.radiantcms.org/mailman/listinfo/radiant