From 9a5a196d79ed8692c45595c4e3d42e34571bc3a7 Mon Sep 17 00:00:00 2001 From: Frédéric Buclin Date: Tue, 17 Apr 2012 20:56:41 +0200 Subject: Bug 745197: Add a hook in Bugzilla::Error::_throw_error() so that extensions can control the way to throw errors r=dkl a=LpSolit --- Bugzilla/Error.pm | 91 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 43 deletions(-) (limited to 'Bugzilla/Error.pm') diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm index ebe8decbd..e1df5ddbb 100644 --- a/Bugzilla/Error.pm +++ b/Bugzilla/Error.pm @@ -77,56 +77,61 @@ sub _throw_error { } my $template = Bugzilla->template; - if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { - print Bugzilla->cgi->header(); - $template->process($name, $vars) - || ThrowTemplateError($template->error()); - } + 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. + if (Bugzilla->error_mode != ERROR_MODE_TEST) { + $template->process($name, $vars, \$message) + || ThrowTemplateError($template->error()); + } + + # Let's call the hook first, so that extensions can override + # or extend the default behavior, or add their own error codes. + Bugzilla::Hook::process('error_catch', { error => $error, vars => $vars, + message => \$message }); + + if (Bugzilla->error_mode == ERROR_MODE_WEBPAGE) { + print Bugzilla->cgi->header(); + print $message; + } elsif (Bugzilla->error_mode == ERROR_MODE_TEST) { die Dumper($vars); } - else { - my $message; - $template->process($name, $vars, \$message) - || ThrowTemplateError($template->error()); - if (Bugzilla->error_mode == ERROR_MODE_DIE) { - die("$message\n"); + elsif (Bugzilla->error_mode == ERROR_MODE_DIE) { + die("$message\n"); + } + elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT + || Bugzilla->error_mode == ERROR_MODE_JSON_RPC) + { + # Clone the hash so we aren't modifying the constant. + my %error_map = %{ WS_ERROR_CODE() }; + Bugzilla::Hook::process('webservice_error_codes', + { error_map => \%error_map }); + my $code = $error_map{$error}; + if (!$code) { + $code = ERROR_UNKNOWN_FATAL if $name =~ /code/i; + $code = ERROR_UNKNOWN_TRANSIENT if $name =~ /user/i; + } + + if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) { + die SOAP::Fault->faultcode($code)->faultstring($message); } - elsif (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT - || Bugzilla->error_mode == ERROR_MODE_JSON_RPC) - { - # Clone the hash so we aren't modifying the constant. - my %error_map = %{ WS_ERROR_CODE() }; - Bugzilla::Hook::process('webservice_error_codes', - { error_map => \%error_map }); - my $code = $error_map{$error}; - if (!$code) { - $code = ERROR_UNKNOWN_FATAL if $name =~ /code/i; - $code = ERROR_UNKNOWN_TRANSIENT if $name =~ /user/i; - } - - if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) { - die SOAP::Fault->faultcode($code)->faultstring($message); - } - else { - my $server = Bugzilla->_json_server; - # 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); - # 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 - # it checks $@, so it returns the proper error. - die if _in_eval(); - $server->response($server->error_response_header); - } + else { + my $server = Bugzilla->_json_server; + # 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); + # 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 + # it checks $@, so it returns the proper error. + die if _in_eval(); + $server->response($server->error_response_header); } } exit; -- cgit v1.2.3-24-g4f1b