]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1263244 - Throw*Error inside templates should always use die(), as if error_mode...
authorDylan William Hardison <dylan@hardison.net>
Tue, 20 Sep 2016 22:19:47 +0000 (18:19 -0400)
committerDylan William Hardison <dylan@hardison.net>
Tue, 20 Sep 2016 22:19:47 +0000 (18:19 -0400)
r=dkl,a=dylan

Bugzilla.pm
Bugzilla/Error.pm
Bugzilla/Template.pm

index a8917aab8090a9454739a25ee254d9c977ce21dd..ada2cc32660ca2685781086558258f589a2310b5 100644 (file)
@@ -76,8 +76,6 @@ use constant SHUTDOWNHTML_RETRY_AFTER => 3600;
 # Global Code
 #####################################################################
 
-#$::SIG{__DIE__} = i_am_cgi() ? \&CGI::Carp::confess : \&Carp::confess;
-
 # Note that this is a raw subroutine, not a method, so $class isn't available.
 sub init_page {
     if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
index 394e0a5e5eaf74c443eafe358cf43370422e53e1..198460354b93a37b8c34a97c01335bb495277250 100644 (file)
@@ -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");
index 40079339a4f14e66a5e273bddf160278a9f3cd8c..8871d810da2d627520927003fc41fa67d3c0bcb8 100644 (file)
@@ -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;