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
-~----------~----~----~----~------~----~------~--~---

Reply via email to