On Sep 27, 2006, at 1:29 PM, Alberto Valverde wrote:
>
>
> On Sep 27, 2006, at 1:10 PM, Timur Izhbulatov wrote:
>
>>
>> Hi,
>>
>> I got a problem using @exception_handler together with Cheetah.
>>
>> Consider a situation:
>>
>> # in cheetah1/controllers.py
>> from turbogears import controllers, expose, exception_handler
>>
>> class Root(controllers.RootController):
>> def get_data(self):
>> raise ValueError('Error!')
>> return dict(a=1)
>>
>> def error(self, tg_exceptions=None):
>> return dict(exception=str(tg_exceptions))
>>
>> @exception_handler(error, rules="True")
>> @expose(template="cheetah:cheetah1.templates.site")
>> def index(self):
>> data = self.get_data()
>> return data
>>
>> # in cheetah1/templates/site.tmpl
>> a: $a
>>
>> I expect @exception_handler to handle the ValueError exception
>> before @expose
>> renders the template. But it looks like @expose is called before
>> @exception_handler and Cheetah.Template.NotFound raises. In this
>> situation I
>> have to handle the exception in the method body and change the
>> template
>> dynamicaly:
>>
>> @expose(template="cheetah:cheetah1.templates.site")
>> def index(self):
>> try:
>> data = self.get_data()
>> except ValueError, error:
>> return (dict
>> (tg_template='cheetah:cheetah1.templates.error',
>> error=error))
>> return data
>>
>> But @exception_handler is not used and I lose all the benefits it
>> gives! Is it
>> posible to solve this problem without writing custom template
>> plugin/decorator/whatever?
>>
>> Thanks in advance,
>
> errorhandling only catches exceptions raised *inside* controller
> methods (well, and SA's run_with_transaction to catch db backend
> exceptions). The exception from Cheetah is raised somewhere inside
> expose so errorhandling can't help you there, sorry :(
>
> You could use the internal view._choose_engine function (though,
> being internal, I'd rather not endorse doing it) to load the template
> inside your controller (or by using a decorator which stacks before
> expose in order to give errorhandling a chance to trap it) and then
> returning the loaded ttemplate at tg_template.
Actually, to check if the template really exists you''ll need to
actually load the template with the engine. Something like:
from tubogears.decorator import weak_signature_decorator
from turbogears.view import _choose_engine
def load_template(template):
def _load_template(template):
engine, template, enginename = _choose_engine(template)
if isinstance(template, basestring):
# Only try to load template if it's not already loaded
template = engine.load_template(template)
return template
def entangle(func):
def template_loader(*args, **kw):
template = _load_template(template)
output = func(*args, **kw)
if isinstance(output, dict):
# I'm not too confident that tg_template can be
a compiled
# template, maybe you need to pass the template
name
# and let expose reload it.
output['tg_template'] = template
return output
return template_loader
return weak_signature_decorator(entangle)
DISCLAIMER: Code written in Mail, might need some tweaking/more-
extensive-error-checking
You need to stack this decorator *before* expose.
Alberto
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/turbogears
-~----------~----~----~----~------~----~------~--~---