Nasty bug in TT 2.14

This is a warning to anyone using Template Toolkit version 2.14. If you call a Perl method from your template, and that method dies (throws an exception), then TT might catch that exception and silently ignore it. It took me a while to figure this out because at first I couldn't reproduce the problem in a simple test program, but it turns out that it only ignores errors which contain the string “Can't locate object method”. Unfortunately, you can get this kind of error from a simple typo in the name of a method you're calling, or as in my case by getting your objects mixed up and calling a method on the wrong one.

Here's a simple example template, which calls a method it expects to get a return value from, but which will die (and should therefore stop the execution of the template in its tracks):

Before calling method.
[% my_object.dieing_method %]
After calling method.

This runs it and provides the dieing method, which has a simple typo in:

#!/usr/bin/perl
use warnings;
use strict;


package MyClass;
use DateTime;

sub new { bless {}, shift }

sub dieing_method {
    print STDERR "About to die\n";
    my $today = DateTime->toady;    # whoops
    print STDERR "Failed to die\n";
    return $today->ymd;
}


package main;
use Template;

my $tt = Template->new({ })
    or die $Template::ERROR;

my %vars = ( my_object => MyClass->new );
$tt->process('tt-die.tt', \%vars, \*STDOUT)
    or die $Template::ERROR;

With Template Toolkit 2.15 this works, and you get a helpful error message which makes it trivial to find the problem. But with version 2.14 it's as though the method just returned an empty string. If your broken method call is buried deep in function calls then you can look forward to hours of inserting print statements to figure out where your Perl code suddenly stops, silently.

So OK, this bug is fixed now, but it was in the stable version of TT from October 2004 to May 2006, and still is in the latest version available in Debian unstable. I know I've been caught out by it in the past, and it cost be hours to track down a problem this time around.

I'm going to require version 2.15 for Daizu, and hope that doesn't have any similarly crippling bugs.

For reference, here's the changelog message, where the bug was fixed in the developer release 2.14a:

Changed Template::Stash to be a little more strict about what it considers a failed method call. This allows exception thrown within called methods to be propagated correctly rather than being ignored as undefined method. Thanks to Dave Howorth, Tom Insam and Stig Brautaset for reporting the problem and providing fixes.

http://tt2.org/pipermail/templates/2005-April/007375.html
http://tt2.org/pipermail/templates/2006-February/008367.html

< Bug adding namespaced attributes | Displaying null values in psql >