
テンプレートのエラーが出た時にアプリケーションのログだけに書くのでは無く、誰にでも「ここがえらってるよ!」って見えるようにしとくと間違いが少なくなる傾向があるのでテンプレートエンジンでフック出来るようになっておいてたら、それをうまく使うと良い。
また、テンプレートエンジンがレンダリングしてるフェーズで DB にクエリが飛ぶような構造で書いてあると、非エンジニアのカジュアルにテンプレートいじる人が甚大なクエリを実装してしまう可能性があるので、これも早期に発見しないとサービスが止まってしまい会社の売り上げが下がってしまい社員が路頭に迷うケースが発生してしまうので、これらも未然に防がなければならない。
Text::Xslate + Amon2 ならこうかける。
package MyProje::Web;
...;
{
my $view_conf = __PACKAGE__->config->{'Text::Xslate'} || +{};
if ($ENV{PLACK_ENV} eq 'development') {
$view_conf->{warn_handler} = sub {
warn @_;
Text::Xslate->print(
Text::Xslate::mark_raw('<span style="color: red; font-size: 1.8em;">'),
'[[', @_, ']]',
Text::Xslate::mark_raw('</span>')
);
};
}
my $view = Text::Xslate->new(%{ $view_conf });
sub create_view { $view }
}
...
sub render {
my ($c, $tmpl, $vars) = @_;
if ($ENV{PLACK_ENV} eq 'development') {
require DBIx::Tracer;
$tracer = DBIx::Tracer->new(
sub {
return unless Text::Xslate->current_engine;
my %args = @_;
my $sql = $args{sql};
warn "Do not execute query in a view: $sql";
Text::Xslate->print(
Text::Xslate::mark_raw('<span style="color: red; font-size: 1.8em;">'),
"[[ Do not execute query in a view: $sql ]]",
Text::Xslate::mark_raw('</span>')
);
}
);
}
$c->SUPER::render($tmpl, $vars);
}
ログに吐いておいたらエンジニアくらいにしか気づかないが、ブラウザから分かるように真っ赤に大きく明らかなエラーっぽいのを返す事でアンテナの感度が低めな人にも「なんかおかしいよこれ」って言ってもらえるので、結果的には事故が未然に防げておいしいご飯と暖かい布団で生活出来るようになるわけである。
こんかいは、うっかり Perl で例を書いたが他の言語でも応用が利くでしょう。
参考文献
Xslate 1.0006 released! - Islands in the byte stream
How can I deny a DB access in a view? - tokuhirom's blog.