diff options
Diffstat (limited to 'Bugzilla/Error.pm')
-rw-r--r-- | Bugzilla/Error.pm | 107 |
1 files changed, 86 insertions, 21 deletions
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index 178f6f90c..41345e11b 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -26,8 +26,9 @@ package Bugzilla::Error; use strict; use base qw(Exporter); -@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError); +@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError ThrowErrorPage); +use Bugzilla::Sentry; use Bugzilla::Constants; use Bugzilla::WebService::Constants; use Bugzilla::Util; @@ -93,6 +94,7 @@ sub _throw_error { my $template = Bugzilla->template; my $message; + # 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. @@ -108,8 +110,20 @@ sub _throw_error { message => \$message }); if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { + if (sentry_should_notify($vars->{error})) { + $vars->{maintainers_notified} = 1; + $vars->{processed} = {}; + } else { + $vars->{maintainers_notified} = 0; + } + print Bugzilla->cgi->header(); - print $message; + $template->process($name, $vars) + || ThrowTemplateError($template->error()); + + if ($vars->{maintainers_notified}) { + sentry_handle_error($vars->{error}, $vars->{processed}->{error_message}); + } } elsif (Bugzilla->error_mode == ERROR_MODE_TEST) { die Dumper($vars); @@ -118,7 +132,8 @@ sub _throw_error { die("$message\n"); } elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT - || Bugzilla->error_mode == ERROR_MODE_JSON_RPC) + || Bugzilla->error_mode == ERROR_MODE_JSON_RPC + || Bugzilla->error_mode == ERROR_MODE_REST) { # Clone the hash so we aren't modifying the constant. my %error_map = %{ WS_ERROR_CODE() }; @@ -135,13 +150,20 @@ sub _throw_error { } else { my $server = Bugzilla->_json_server; + + my $status_code = 0; + if (Bugzilla->error_mode == ERROR_MODE_REST) { + my %status_code_map = %{ REST_STATUS_CODE_MAP() }; + $status_code = $status_code_map{$code} || $status_code_map{'_default'}; + } # Technically JSON-RPC isn't allowed to have error numbers # higher than 999, but we do this to avoid conflicts with # the internal JSON::RPC error codes. - $server->raise_error(code => 100000 + $code, - message => $message, - id => $server->{_bz_request_id}, - version => $server->version); + $server->raise_error(code => 100000 + $code, + status_code => $status_code, + message => $message, + id => $server->{_bz_request_id}, + version => $server->version); # Most JSON-RPC Throw*Error calls happen within an eval inside # of JSON::RPC. So, in that circumstance, instead of exiting, # we die with no message. JSON::RPC checks raise_error before @@ -183,40 +205,83 @@ sub ThrowTemplateError { die("error: template error: $template_err"); } + # mod_perl overrides exit to call die with this string + # we never want to display this to the user + exit if $template_err =~ /\bModPerl::Util::exit\b/; + $vars->{'template_error_msg'} = $template_err; $vars->{'error'} = "template_error"; + sentry_handle_error('error', $template_err); + $vars->{'template_error_msg'} =~ s/ at \S+ line \d+\.\s*$//; + my $template = Bugzilla->template; # Try a template first; but if this one fails too, fall back # on plain old print statements. if (!$template->process("global/code-error.html.tmpl", $vars)) { - my $maintainer = Bugzilla->params->{'maintainer'}; + my $maintainer = html_quote(Bugzilla->params->{'maintainer'}); my $error = html_quote($vars->{'template_error_msg'}); my $error2 = html_quote($template->error()); print <<END; <tt> <p> - Bugzilla has suffered an internal error. Please save this page and - send it to $maintainer with details of what you were doing at the - time this message appeared. + Bugzilla has suffered an internal error: + </p> + <p> + $error + </p> + <!-- template error, no real need to show this to the user + $error2 + --> + <p> + The <a href="mailto:$maintainer">Bugzilla maintainers</a> have + been notified of this error. </p> - <script type="text/javascript"> <!-- - document.write("<p>URL: " + - document.location.href.replace(/&/g,"&") - .replace(/</g,"<") - .replace(/>/g,">") + "</p>"); - // --> - </script> - <p>Template->process() failed twice.<br> - First error: $error<br> - Second error: $error2</p> </tt> END } exit; } +sub ThrowErrorPage { + # BMO customisation for bug 659231 + my ($template_name, $message) = @_; + + my $dbh = Bugzilla->dbh; + $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction(); + + if (Bugzilla->error_mode == ERROR_MODE_DIE) { + die("error: $message"); + } + + if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT + || Bugzilla->error_mode == ERROR_MODE_JSON_RPC) + { + my $code = ERROR_UNKNOWN_TRANSIENT; + if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) { + die SOAP::Fault->faultcode($code)->faultstring($message); + } else { + my $server = Bugzilla->_json_server; + $server->raise_error(code => 100000 + $code, + message => $message, + id => $server->{_bz_request_id}, + version => $server->version); + die if _in_eval(); + $server->response($server->error_response_header); + } + } else { + my $cgi = Bugzilla->cgi; + my $template = Bugzilla->template; + my $vars = {}; + $vars->{message} = $message; + print $cgi->header(); + $template->process($template_name, $vars) + || ThrowTemplateError($template->error()); + exit; + } +} + 1; __END__ |