[Dancer-users] Exception in before_template_render hook does not render error_template

Alex C calyx238 at gmail.com
Sat Apr 14 19:03:24 CEST 2012


Following this up, it turns out that "before_template_render" is the
only logical place I can put my potentially-fatal code. So I decided
to wrap my database call in an eval{} and log an error() myself, to
make sure that my error_template is always displayed. However, this
resulted in duplicate entries appearing in the error log when an
exception was raised: first by the exception itself, and then again
when my error_template was being rendered (in addition to a useless
database hit). The solution I finally came up with is this:

hook before_error_render => sub {
    var error_thrown => 1;
};

hook before_template_render => sub {
    unless ( vars->{error_thrown} ) {
        eval { potentially_fatal() };
        error $@,"\n" if $@;
    }
}

...and there goes half my weekend :(

On 14 April 2012 14:44, Alex C <calyx238 at gmail.com> wrote:
> After some thought, I realise that patching this is a bad idea because
> then the before_template_render hook will not be called after any
> exception.
>
> Instead I will move my database call outide the hook, and I can add a
> small note to the error_template documentation.
>
> Sorry for the noise!
>
> On 14 April 2012 06:57, Alex C <calyx238 at gmail.com> wrote:
>> I noticed this when trying to make a database call in the
>> before_template_render hook (to conditionally set a token if a row
>> exists). To reproduce:
>>
>> $ echo "my custom error message" > views/error.tt
>>
>> ---------
>> package App;
>> use Dancer ':syntax';
>>
>> set show_errors => 0;
>> set error_template => 'error.tt';
>>
>> hook before_template_render => sub {    die;    };
>>
>> get '/' => sub {    template 'index.tt';    };
>>
>> true;
>> ---------
>>
>> It can be resolved by adding a simple check inside
>> Dancer::Template::Abstract::apply_renderer() :
>>
>> ---------
>> @@ -73,9 +73,13 @@ sub apply_renderer {
>>
>>     ($tokens, undef) = _prepare_tokens_options($tokens);
>>
>> +    my $is_error_template
>> +        = $view eq Dancer::Config::setting('error_template') ? 1 : 0;
>> +
>>     $view = $self->view($view);
>>
>> -    Dancer::Factory::Hook->execute_hooks('before_template_render', $tokens);
>> +    Dancer::Factory::Hook->execute_hooks('before_template_render', $tokens)
>> +        unless $is_error_template;
>> ---------
>>
>> Is it worth making a PR for this?
>>
>> --
>> Alex


More information about the Dancer-users mailing list