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