diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index d6ad83532..1ff43e9f1 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -4,6 +4,7 @@ - fixed: getNextThread/getPreviousThread won't sort by thread rating - fixed: #10485: User not returned to asset manager after adding content to /impor - fixed: #10262: Default Inbox View Template: Mismatch in HTML for upper and lower page navigation + - fixed rfe #10474: Improve error message for template errors 7.7.9 - fixed #10266: Public Profile overrides Able to be friend diff --git a/lib/WebGUI/Asset/Template.pm b/lib/WebGUI/Asset/Template.pm index b75bdbad0..0e8a2be25 100644 --- a/lib/WebGUI/Asset/Template.pm +++ b/lib/WebGUI/Asset/Template.pm @@ -20,6 +20,7 @@ use WebGUI::International; use WebGUI::Asset::Template::HTMLTemplate; use WebGUI::Utility; use WebGUI::Form; +use WebGUI::Exception; use Tie::IxHash; use Clone qw/clone/; use HTML::Packer; @@ -374,9 +375,9 @@ sub getEditForm { ); my ($style, $url) = $self->session->quick(qw(style url)); - $style->setScript($url->extras('yui/build/yahoo/yahoo-min.js')); - $style->setScript($url->extras('yui/build/json/json-min.js')); - $style->setScript($url->extras('yui/build/dom/dom-min.js')); + $style->setScript($url->extras('yui/build/yahoo/yahoo-min.js'), {type => 'text/javascript'}); + $style->setScript($url->extras('yui/build/json/json-min.js'), {type => 'text/javascript'}); + $style->setScript($url->extras('yui/build/dom/dom-min.js'), {type => 'text/javascript'}); pop(@headers); my $scriptUrl = $url->extras('templateAttachments.js'); @@ -595,7 +596,14 @@ sub process { ? $self->get('templatePacked') : $self->get('template') ; - return $parser->process($template, $vars); + my $output; + eval { $output = $parser->process($template, $vars); }; + if (my $e = Exception::Class->caught) { + $self->session->log->error(sprintf "Error processing template: %s, %s, %s", $self->getUrl, $self->getId, $e->error); + my $i18n = WebGUI::International->new($self->session, 'Asset_Template'); + $output = sprintf $i18n->get('template error').$e->error, $self->getUrl, $self->getId; + } + return $output; } diff --git a/lib/WebGUI/Asset/Template/HTMLTemplate.pm b/lib/WebGUI/Asset/Template/HTMLTemplate.pm index c31851ed6..ed95d8345 100644 --- a/lib/WebGUI/Asset/Template/HTMLTemplate.pm +++ b/lib/WebGUI/Asset/Template/HTMLTemplate.pm @@ -16,6 +16,7 @@ package WebGUI::Asset::Template::HTMLTemplate; use strict; use base 'WebGUI::Asset::Template::Parser'; +use WebGUI::Exception; use HTML::Template; @@ -37,7 +38,7 @@ sub getName { =head2 process ( template, vars ) -Evaluate a template replacing template commands for HTML. +Evaluate a template replacing template commands for HTML. =head3 template @@ -50,28 +51,25 @@ A hash reference containing template variables and loops. =cut sub process { - my $self = shift; - my $template = shift; - my $vars = $self->addSessionVars(shift); - my $t; - eval { - $t = HTML::Template->new( - scalarref=>\$template, - global_vars=>1, - loop_context_vars=>1, - die_on_bad_params=>0, - no_includes=>1, - strict=>0 - ); - }; - unless ($@) { - $t->param(%{$vars}); - return $t->output; - } else { - $self->session->errorHandler->error("Error in template. ".$@); - return WebGUI::International->new($self->session, 'Asset_Template')->get('template error').$@; - } + my $self = shift; + my $template = shift; + my $vars = $self->addSessionVars(shift); + my $t; + eval { + $t = HTML::Template->new( + scalarref=>\$template, + global_vars=>1, + loop_context_vars=>1, + die_on_bad_params=>0, + no_includes=>1, + strict=>0 + ); + }; + if ($@) { + WebGUI::Error::Template->throw( error => $@ ); + } + $t->param(%{$vars}); + return $t->output; } - 1; diff --git a/lib/WebGUI/Asset/Template/HTMLTemplateExpr.pm b/lib/WebGUI/Asset/Template/HTMLTemplateExpr.pm index 9b1ca3d27..3f6984244 100644 --- a/lib/WebGUI/Asset/Template/HTMLTemplateExpr.pm +++ b/lib/WebGUI/Asset/Template/HTMLTemplateExpr.pm @@ -17,6 +17,7 @@ package WebGUI::Asset::Template::HTMLTemplateExpr; use strict; use base 'WebGUI::Asset::Template::Parser'; use HTML::Template::Expr; +use WebGUI::Exception; #------------------------------------------------------------------- @@ -77,25 +78,23 @@ A hash reference containing template variables and loops. # about the template that has the error. Finding an "ERROR: Error in template" # in the error log is not very helpful... sub process { - my $class = shift; - my $template = shift; - my $vars = $class->addSessionVars(shift); - my $t; - eval { - $t = HTML::Template::Expr->new(scalarref=>\$template, - global_vars=>1, - loop_context_vars=>1, - die_on_bad_params=>0, - no_includes=>1, - strict=>0); - }; - unless ($@) { - $t->param(%{_rewriteVars($vars)}); - return $t->output; - } else { - $class->session->errorHandler->error("Error in template. ".$@); - return WebGUI::International->new($class->session,'Asset_Template')->get('template error').$@; - } + my $class = shift; + my $template = shift; + my $vars = $class->addSessionVars(shift); + my $t; + eval { + $t = HTML::Template::Expr->new(scalarref=>\$template, + global_vars=>1, + loop_context_vars=>1, + die_on_bad_params=>0, + no_includes=>1, + strict=>0); + }; + if ($@) { + WebGUI::Error::Template->throw( error => $@ ); + } + $t->param(%{_rewriteVars($vars)}); + return $t->output; } 1; diff --git a/lib/WebGUI/Asset/Template/TemplateToolkit.pm b/lib/WebGUI/Asset/Template/TemplateToolkit.pm index 2de1989a1..3474dedda 100644 --- a/lib/WebGUI/Asset/Template/TemplateToolkit.pm +++ b/lib/WebGUI/Asset/Template/TemplateToolkit.pm @@ -71,25 +71,22 @@ A hash reference containing template variables and loops. # about the template that has the error. Finding an "ERROR: Error in template" # in the error log is not very helpful... sub process { - my $self = shift; - my $template = shift; - my $vars = $self->addSessionVars(shift); - my ($t,$output); - eval { - $t = Template->new( { - INTERPOLATE => 1, # expand "$var" in plain text - POST_CHOMP => 1, # cleanup whitespace - EVAL_PERL => 0, # evaluate Perl code blocks - }); - $t->process( \$template, _rewriteVars($vars),\$output) || $self->session->errorHandler->error($t->error()); - }; - unless($@){ - return $output; - } else { - $self->session->errorHandler->error("Error in template. ".$@); - return WebGUI::International->new($self->session,'Asset_Template')->get('template error').$@; - } - + my $self = shift; + my $template = shift; + my $vars = $self->addSessionVars(shift); + my ($t,$output); + eval { + $t = Template->new({ + INTERPOLATE => 1, # expand "$var" in plain text + POST_CHOMP => 1, # cleanup whitespace + EVAL_PERL => 0, # evaluate Perl code blocks + }); + $t->process( \$template, _rewriteVars($vars),\$output) || $self->session->errorHandler->error($t->error()); + }; + if ($@) { + WebGUI::Error::Template->throw( error => $@ ); + } + return $output; } 1; diff --git a/lib/WebGUI/Asset/Template/_parser.skeleton b/lib/WebGUI/Asset/Template/_parser.skeleton index 321db6508..88109604a 100644 --- a/lib/WebGUI/Asset/Template/_parser.skeleton +++ b/lib/WebGUI/Asset/Template/_parser.skeleton @@ -16,6 +16,7 @@ package WebGUI::Asset::Template::SomeTemplateType; use strict; use base 'WebGUI::Asset::Template::Parser'; +use WebGUI::Exception; #------------------------------------------------------------------- @@ -52,7 +53,12 @@ sub process { my $self = shift; my $template = shift; my $vars = $self->addSessionVars(shift); - ... + eval { + + } + if ($@) { + WebGUI::Error::Template->throw( error => $@ ); + } } diff --git a/lib/WebGUI/Exception.pm b/lib/WebGUI/Exception.pm index e7c4f3a78..3d4ac9872 100644 --- a/lib/WebGUI/Exception.pm +++ b/lib/WebGUI/Exception.pm @@ -54,6 +54,10 @@ use Exception::Class ( description => "The file you have provided has errors.", fields => [qw{ brokenFile brokenLine }], }, + 'WebGUI::Error::Template' => { + isa => 'WebGUI::Error', + description => "A template has errors that prevent it from being processed.", + }, ); diff --git a/lib/WebGUI/i18n/English/Asset_Template.pm b/lib/WebGUI/i18n/English/Asset_Template.pm index 6ca15e990..a431ee5da 100644 --- a/lib/WebGUI/i18n/English/Asset_Template.pm +++ b/lib/WebGUI/i18n/English/Asset_Template.pm @@ -33,9 +33,9 @@ our $I18N = { }, 'template error' => { - message => q|There is a syntax error in this template. Please correct.|, + message => q|There is a syntax error in this template, %s, %s. Please correct.|, context => q|Error when executing template|, - lastUpdated => 1107391368, + lastUpdated => 1244476530, }, 'namespace description' => { diff --git a/t/Asset/Template.t b/t/Asset/Template.t index 605ff673e..9d11fac02 100644 --- a/t/Asset/Template.t +++ b/t/Asset/Template.t @@ -15,7 +15,8 @@ use lib "$FindBin::Bin/../lib"; use WebGUI::Test; use WebGUI::Session; use WebGUI::Asset::Template; -use Test::More tests => 32; # increment this value for each test you create +use Exception::Class; +use Test::More tests => 37; # increment this value for each test you create use Test::Deep; my $session = WebGUI::Test->session; @@ -109,11 +110,24 @@ is(@$att4, 3, 'rev is proper size'); $template3rev->purgeRevision(); +my $brokenTemplate = $importNode->addChild({ + className => "WebGUI::Asset::Template", + title => 'Broken template', + template => q|If clause with no ending tag|, +}); # done checking revision stuff -$template->purge; -$templateCopy->purge; -$template3->purge; -WebGUI::VersionTag->getWorking($session)->rollback; +WebGUI::Test->interceptLogging; +my $brokenOutput = $brokenTemplate->process({}); +my $logError = $WebGUI::Test::logger_error; +my $brokenUrl = $brokenTemplate->getUrl; +my $brokenId = $brokenTemplate->getId; +like($brokenOutput, qr/^There is a syntax error in this template/, 'process: returned error output contains boilerplate'); +like($brokenOutput, qr/$brokenUrl/, '... and the template url'); +like($brokenOutput, qr/$brokenId/, '... and the template id'); +like($logError, qr/$brokenUrl/, 'process: logged error has the url'); +like($logError, qr/$brokenId/, '... and the template id'); + +WebGUI::Test->tagsToRollback(WebGUI::VersionTag->getWorking($session));