diff options
author | Frédéric Buclin <LpSolit@gmail.com> | 2012-04-17 20:56:41 +0200 |
---|---|---|
committer | Frédéric Buclin <LpSolit@gmail.com> | 2012-04-17 20:56:41 +0200 |
commit | 9a5a196d79ed8692c45595c4e3d42e34571bc3a7 (patch) | |
tree | 058a2aba35e324354547f7d45e504282b3eb98a5 /Bugzilla | |
parent | 3b2fcf526e02c1d74f88b567083a9be371d5a607 (diff) | |
download | bugzilla-9a5a196d79ed8692c45595c4e3d42e34571bc3a7.tar.gz bugzilla-9a5a196d79ed8692c45595c4e3d42e34571bc3a7.tar.xz |
Bug 745197: Add a hook in Bugzilla::Error::_throw_error() so that extensions can control the way to throw errors
r=dkl a=LpSolit
Diffstat (limited to 'Bugzilla')
-rw-r--r-- | Bugzilla/Error.pm | 91 | ||||
-rw-r--r-- | Bugzilla/Hook.pm | 31 |
2 files changed, 79 insertions, 43 deletions
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; diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 8eac561c0..27184c2e4 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -687,6 +687,37 @@ Params: =back +=head2 error_catch + +This hook allows extensions to catch errors thrown by Bugzilla and +take the appropriate actions. + +Params: + +=over + +=item C<error> + +A string representing the error code thrown by Bugzilla. This string +matches the C<error> variable in C<global/user-error.html.tmpl> and +C<global/code-error.html.tmpl>. + +=item C<message> + +If the error mode is set to C<ERROR_MODE_WEBPAGE>, you get a reference to +the whole HTML page with the error message in it, including its header and +footer. If you need to extract the error message itself, you can do it by +looking at the content of the table cell whose ID is C<error_msg>. +If the error mode is not set to C<ERROR_MODE_WEBPAGE>, you get a reference +to the error message itself. + +=item C<vars> + +This hash contains all the data passed to the error template. Its content +depends on the error thrown. + +=back + =head2 flag_end_of_update This happens at the end of L<Bugzilla::Flag/update_flags>, after all other |