Myk Melez wrote:
: ...  I'm trying to simplify the code by removing exception handling from the line 
:where I call $::template->process.  So instead of doing this every time I want to 
:call a template:
: 
: $::template->process("MyTemplate.atml", $::vars)
:   || MyExceptionHandlingFunction($::template->error());
: 
: I do this once:
: 
: $::template = Template->new(
:   {
:     ERROR => 'MyErrorTemplate.atml'
:   }
: );
: 
: And then process a template with:
: 
: $::template->process("MyTemplate.atml", $::vars);
: 
: This makes my code cleaner and reduces redundancy when processing a number of 
:templates, but it doesn't work because the toolkit only processes the error template 
:when I throw an exception explicitly; toolkit-thrown errors don't cause trigger the 
:error template.

Usually I write my code to call process() only once, so I'm comfortable
catching the exceptions. But...

Suggestion #1 (somewhat kludgy): Write your own processor:

sub Template::myProcess {
        my ($template,@args) = @_;
        eval { $template->process(@args) };
        if ($@) {
                # do here whatever MyExceptionHandlingFunction does
        }
}

Then in your code, call that instead of process():

my $template = Template->new();
...
$template->myProcess("MyTemplate.atml", $::vars);

Suggestion #2: Write a simple subclass of Template that overrides
process() by calling $template->SUPER::process() inside an eval. This
is either a kludge or a Design Pattern. ;)

A more general solution would be if there were a TEMPLATE_ERROR
config option. Something like this:

my $template = Template->new({
        TEMPLATE_ERROR => &TemplateExceptionHandler,
});

sub TemplateExceptionHandler {
        my ($template) = @_;
        print STDOUT "<h2>Error</h2>\n";
        print STDOUT "An unrecoverable error has occured:\n";
        print STDOUT "<pre>", $template->error(), "</pre>";
        die $template->error();
}

Have process() catch all exceptions. If TEMPLATE_ERROR is defined,
then $template->process() will execute the exception handler. If not,
it re-dies(). I'd have it take a sub ref instead of a template name,
because if you get an uncaught exception processing one template, you
probably shouldn't try to die gracefully by processing another.

-- tdk


Reply via email to