From 2f4472f335e6baea7ac5b1d12c9bfa50bd58c1a2 Mon Sep 17 00:00:00 2001 From: Dylan William Hardison Date: Tue, 20 Sep 2016 18:19:47 -0400 Subject: Bug 1263244 - Throw*Error inside templates should always use die(), as if error_mode is ERROR_MODE_DIE r=dkl,a=dylan --- Bugzilla/Error.pm | 19 +++++++++++++++++-- Bugzilla/Template.pm | 3 +++ 2 files changed, 20 insertions(+), 2 deletions(-) (limited to 'Bugzilla') diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index 394e0a5e5..198460354 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -22,6 +22,7 @@ use Bugzilla::Hook; use Carp; use Data::Dumper; use Date::Format; +use Scalar::Util qw(blessed); sub _throw_error { my ($name, $error, $vars) = @_; @@ -68,7 +69,7 @@ sub _throw_error { # There are some tests that throw and catch a lot of errors, # and calling $template->process over and over for those errors # is too slow. So instead, we just "die" with a dump of the arguments. - if (Bugzilla->error_mode != ERROR_MODE_TEST) { + if (Bugzilla->error_mode != ERROR_MODE_TEST && !$Bugzilla::Template::is_processing) { $template->process($name, $vars, \$message) || ThrowTemplateError($template->error()); } @@ -78,6 +79,12 @@ sub _throw_error { Bugzilla::Hook::process('error_catch', { error => $error, vars => $vars, message => \$message }); + if ($Bugzilla::Template::is_processing) { + $name =~ /^global\/(user|code)-error/; + my $type = $1 // 'unknown'; + die Template::Exception->new("bugzilla.$type.$error", $vars); + } + if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { my $cgi = Bugzilla->cgi; $cgi->close_standby_message('text/html', 'inline', 'error', 'html'); @@ -149,7 +156,7 @@ sub ThrowCodeError { # Don't show the error as coming from Bugzilla::Error, show it # as coming from the caller. local $Carp::CarpInternal{'Bugzilla::Error'} = 1; - $vars->{traceback} = Carp::longmess(); + $vars->{traceback} //= Carp::longmess(); _throw_error("global/code-error.html.tmpl", @_); } @@ -161,6 +168,14 @@ sub ThrowTemplateError { # Make sure the transaction is rolled back (if supported). $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction(); + if (blessed($template_err) && $template_err->isa('Template::Exception')) { + my $type = $template_err->type; + if ($type =~ /^bugzilla\.(code|user)\.(.+)/) { + _throw_error("global/$1-error.html.tmpl", $2, $template_err->info); + return; + } + } + my $vars = {}; if (Bugzilla->error_mode == ERROR_MODE_DIE) { die("error: template error: $template_err"); diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 40079339a..8871d810d 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -698,12 +698,15 @@ $Template::Stash::SCALAR_OPS->{ truncate } = ############################################################################### +our $is_processing = 0; + sub process { my $self = shift; # All of this current_langs stuff allows template_inner to correctly # determine what-language Template object it should instantiate. my $current_langs = Bugzilla->request_cache->{template_current_lang} ||= []; unshift(@$current_langs, $self->context->{bz_language}); + local $is_processing = 1; my $retval = $self->SUPER::process(@_); shift @$current_langs; return $retval; -- cgit v1.2.3-24-g4f1b