diff options
author | bbaetz%acm.org <> | 2003-04-02 22:35:00 +0200 |
---|---|---|
committer | bbaetz%acm.org <> | 2003-04-02 22:35:00 +0200 |
commit | b259c4b4252cde8e7926690f6ba419d2ee7c59fc (patch) | |
tree | ae51804f9db83c0b1a49f79b9e0a1848cdd5e7c7 | |
parent | 747eb2ddd7febfa0e33ccf3797bf48db0defafcc (diff) | |
download | bugzilla-b259c4b4252cde8e7926690f6ba419d2ee7c59fc.tar.gz bugzilla-b259c4b4252cde8e7926690f6ba419d2ee7c59fc.tar.xz |
Bug 199813 - Make all users of ThrowUserError pass $vars in explicitly.
r=gerv
a=justdave
-rw-r--r-- | Bugzilla/Error.pm | 93 | ||||
-rw-r--r-- | Bugzilla/Search.pm | 19 | ||||
-rw-r--r-- | CGI.pl | 22 | ||||
-rwxr-xr-x | attachment.cgi | 28 | ||||
-rwxr-xr-x | describecomponents.cgi | 4 | ||||
-rwxr-xr-x | duplicates.cgi | 23 | ||||
-rw-r--r-- | globals.pl | 5 | ||||
-rwxr-xr-x | post_bug.cgi | 18 | ||||
-rwxr-xr-x | process_bug.cgi | 50 | ||||
-rw-r--r-- | template/en/default/global/user-error.html.tmpl | 42 | ||||
-rwxr-xr-x | token.cgi | 4 | ||||
-rwxr-xr-x | userprefs.cgi | 3 |
12 files changed, 193 insertions, 118 deletions
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm new file mode 100644 index 000000000..64314121a --- /dev/null +++ b/Bugzilla/Error.pm @@ -0,0 +1,93 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# The Initial Developer of the Original Code is Netscape Communications +# Corporation. Portions created by Netscape are +# Copyright (C) 1998 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): Bradley Baetz <bbaetz@acm.org> + +use strict; + +package Bugzilla::Error; + +use base qw(Exporter); + +@Bugzilla::Error::EXPORT = qw(ThrowUserError); + +sub ThrowUserError { + my ($error, $vars, $unlock_tables) = @_; + + $vars ||= {}; + + $vars->{error} = $error; + + # Need to do this until User.pm goes in, so that the footer is correct + $vars->{user} = $::vars->{user}; + + Bugzilla->dbh->do("UNLOCK TABLES") if $unlock_tables; + + # XXX - mod_perl + print "Content-type: text/html\n\n" if !$::vars->{'header_done'}; + + my $template = Bugzilla->template; + $template->process("global/user-error.html.tmpl", $vars) + || &::ThrowTemplateError($template->error()); + + exit; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Error - Error handling utilities for Bugzilla + +=head1 SYNOPSIS + + use Bugzilla::Error; + + ThrowUserError("error_tag", + { foo => 'bar' }); + +=head1 DESCRIPTION + +Various places throughout the Bugzilla codebase need to report errors to the +user. The C<Throw*Error> family of functions allow this to be done in a +generic and localisable manner. + +=head1 FUNCTIONS + +=over 4 + +=item C<ThrowUserError> + +This function takes an error tag as the first argument, and an optional hashref +of variables as a second argument. These are used by the +I<global/user-error.html.tmpl> template to format the error, using the passed +in variables as required. + +An optional third argument may be supplied. If present (and defined), then the +error handling code will unlock the database tables. In the long term, this +argument will go away, to be replaced by transactional C<rollback> calls. There +is no timeframe for doing so, however. + +=back + +=head1 SEE ALSO + +L<Bugzilla|Bugzilla> diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index ead9156ee..1637671f0 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -103,8 +103,8 @@ sub init { my $c = trim($params->param('votes')); if ($c ne "") { if ($c !~ /^[0-9]*$/) { - $::vars->{'value'} = $c; - &::ThrowUserError("illegal_at_least_x_votes"); + &::ThrowUserError("illegal_at_least_x_votes", + { value => $c }); } push(@specialchart, ["votes", "greaterthan", $c - 1]); } @@ -207,8 +207,8 @@ sub init { if (@clist) { push(@specialchart, \@clist); } else { - $::vars->{'email'} = $email; - &::ThrowUserError("missing_email_type"); + ThrowUserError("missing_email_type", + { email => $email }); } } @@ -217,8 +217,8 @@ sub init { my $c = trim($params->param('changedin')); if ($c ne "") { if ($c !~ /^[0-9]*$/) { - $::vars->{'value'} = $c; - &::ThrowUserError("illegal_changed_in_last_x_days"); + &::ThrowUserError("illegal_changed_in_last_x_days", + { value => $c }); } push(@specialchart, ["changedin", "lessthan", $c + 1]); @@ -558,8 +558,8 @@ sub init { push(@list, "$table.keywordid = $id"); } else { - $::vars->{'keyword'} = $v; - &::ThrowUserError("unknown_keyword"); + ThrowUserError("unknown_keyword", + { keyword => $v }); } } my $haveawordterm; @@ -992,8 +992,7 @@ sub SqlifyDate { } my $date = str2time($str); if (!defined($date)) { - $::vars->{'date'} = $str; - &::ThrowUserError("illegal_date"); + &::ThrowUserError("illegal_date", { date => $str }); } return time2str("%Y-%m-%d %H:%M:%S", $date); } @@ -35,6 +35,7 @@ use lib "."; use Bugzilla::Util; use Bugzilla::Config; use Bugzilla::Constants; +use Bugzilla::Error; # Shut up misguided -w warnings about "used only once". For some reason, # "use vars" chokes on me when I try it here. @@ -252,8 +253,7 @@ sub CheckEmailSyntax { my ($addr) = (@_); my $match = Param('emailregexp'); if ($addr !~ /$match/ || $addr =~ /[\\\(\)<>&,;:"\[\] \t\r\n]/) { - $vars->{'addr'} = $addr; - ThrowUserError("illegal_email_address"); + ThrowUserError("illegal_email_address", { addr => $addr }); } } @@ -327,24 +327,6 @@ sub ThrowCodeError { exit; } -# For errors made by the user. -sub ThrowUserError { - ($vars->{'error'}, my $extra_vars, my $unlock_tables) = (@_); - - SendSQL("UNLOCK TABLES") if $unlock_tables; - - # Copy the extra_vars into the vars hash - foreach my $var (keys %$extra_vars) { - $vars->{$var} = $extra_vars->{$var}; - } - - print "Content-type: text/html\n\n" if !$vars->{'header_done'}; - $template->process("global/user-error.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - - exit; -} - # This function should only be called if a template->process() fails. # It tries another template first, because often one template being # broken or missing doesn't mean that they all are. But it falls back on diff --git a/attachment.cgi b/attachment.cgi index 01201a192..51a154645 100755 --- a/attachment.cgi +++ b/attachment.cgi @@ -171,7 +171,8 @@ sub validateCanEdit "attach_id = $attach_id AND submitter_id = $::userid"); FetchSQLData() - || ThrowUserError("illegal_attachment_edit"); + || ThrowUserError("illegal_attachment_edit", + { attach_id => $attach_id }); } sub validateCanChangeAttachment @@ -183,7 +184,8 @@ sub validateCanChangeAttachment AND bugs.bug_id = attachments.bug_id"); my $productid = FetchOneColumn(); CanEditProductId($productid) - || ThrowUserError("illegal_attachment_edit"); + || ThrowUserError("illegal_attachment_edit", + { attach_id => $attachid }); } sub validateCanChangeBug @@ -194,7 +196,8 @@ sub validateCanChangeBug WHERE bug_id = $bugid"); my $productid = FetchOneColumn(); CanEditProductId($productid) - || ThrowUserError("illegal_attachment_edit"); + || ThrowUserError("illegal_attachment_edit_bug", + { bug_id => $bugid }); } sub validateDescription @@ -249,8 +252,8 @@ sub validateContentType if ( $::FORM{'contenttype'} !~ /^(application|audio|image|message|model|multipart|text|video)\/.+$/ ) { - $vars->{'contenttype'} = $::FORM{'contenttype'}; - ThrowUserError("invalid_content_type"); + ThrowUserError("invalid_content_type", + { contenttype => $::FORM{'contenttype'} }); } } @@ -292,11 +295,11 @@ sub validateData # Make sure the attachment does not exceed the maximum permitted size my $len = length($data); if ($maxsize && $len > $maxsize) { - $vars->{'filesize'} = sprintf("%.0f", $len/1024); + my $vars = { filesize => sprintf("%.0f", $len/1024) }; if ( $::FORM{'ispatch'} ) { - ThrowUserError("patch_too_large"); + ThrowUserError("patch_too_large", $vars); } else { - ThrowUserError("file_too_large"); + ThrowUserError("file_too_large", $vars); } } @@ -328,6 +331,9 @@ sub validateObsolete # Make sure the attachment id is valid and the user has permissions to view # the bug to which it is attached. foreach my $attachid (@{$::MFORM{'obsolete'}}) { + # my $vars after ThrowCodeError is updated to not use the global + # vars hash + $vars->{'attach_id'} = $attachid; detaint_natural($attachid) @@ -338,7 +344,7 @@ sub validateObsolete # Make sure the attachment exists in the database. MoreSQLData() - || ThrowUserError("invalid_attach_id"); + || ThrowUserError("invalid_attach_id", $vars); my ($bugid, $isobsolete, $description) = FetchSQLData(); @@ -663,8 +669,8 @@ sub update my $bugid = FetchSQLData(); unless ($bugid) { - $vars->{'bug_id'} = $bugid; - ThrowUserError("invalid_bug_id"); + ThrowUserError("invalid_bug_id", + { bug_id => $bugid }); } # Lock database tables in preparation for updating the attachment. diff --git a/describecomponents.cgi b/describecomponents.cgi index ec46b3d9d..bdb824b82 100755 --- a/describecomponents.cgi +++ b/describecomponents.cgi @@ -83,8 +83,8 @@ my $product = $::FORM{'product'}; my $product_id = get_product_id($product); if (!$product_id) { - $::vars->{'product'} = $product; - ThrowUserError("invalid_product_name"); + ThrowUserError("invalid_product_name", + { product => $product }); } # Make sure the user is authorized to access this product. diff --git a/duplicates.cgi b/duplicates.cgi index a9a3031f3..1a3c08a9f 100755 --- a/duplicates.cgi +++ b/duplicates.cgi @@ -83,8 +83,8 @@ my $product_id; if ($product) { $product_id = get_product_id($product); if (!$product_id) { - $vars->{'product'} = $product; - ThrowUserError("invalid_product_name"); + ThrowUserError("invalid_product_name", + { product => $product }); } } @@ -109,17 +109,17 @@ if (!tie(%dbmcount, 'AnyDBM_File', "data/duplicates/dupes$today", if ($!{ENOENT}) { if (!tie(%dbmcount, 'AnyDBM_File', "data/duplicates/dupes$yesterday", O_RDONLY, 0644)) { - $vars->{'today'} = $today; + my $vars = { today => $today }; if ($!{ENOENT}) { - ThrowUserError("no_dupe_stats"); + ThrowUserError("no_dupe_stats", $vars); } else { $vars->{'error_msg'} = $!; - ThrowUserError("no_dupe_stats_error_yesterday"); + ThrowUserError("no_dupe_stats_error_yesterday", $vars); } } } else { - $vars->{'error_msg'} = $!; - ThrowUserError("no_dupe_stats_error_today"); + ThrowUserError("no_dupe_stats_error_today", + { error_msg => $! }); } } @@ -146,10 +146,11 @@ if (!tie(%before, 'AnyDBM_File', "data/duplicates/dupes$whenever", O_RDONLY, 0644)) { # Ignore file not found errors if (!$!{ENOENT}) { - $vars->{'error_msg'} = $!; - $vars->{'changedsince'} = $changedsince; - $vars->{'whenever'} = $whenever; - ThrowUserError("no_dupe_stats_error_whenever"); + ThrowUserError("no_dupe_stats_error_whenever", + { error_msg => $!, + changedsince => $changedsince, + whenever => $whenever, + }); } } else { # Calculate the deltas diff --git a/globals.pl b/globals.pl index ae656d9ec..38833ce15 100644 --- a/globals.pl +++ b/globals.pl @@ -127,7 +127,6 @@ sub AppendComment { # zero or more digits, OR we have a period followed by one or more digits if ($work_time !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { ThrowUserError("need_numeric_value"); - return; } } else { $work_time = 0 }; @@ -863,8 +862,8 @@ sub DBNameToIdAndCheck { return $result; } - $::vars->{'name'} = $name; - ThrowUserError("invalid_username"); + ThrowUserError("invalid_username", + { name => $name }); } diff --git a/post_bug.cgi b/post_bug.cgi index 670920d43..37a43afb4 100755 --- a/post_bug.cgi +++ b/post_bug.cgi @@ -78,8 +78,8 @@ ValidateComment($comment); my $product = $::FORM{'product'}; my $product_id = get_product_id($product); if (!$product_id) { - $vars->{'product'} = $product; - ThrowUserError("invalid_product_name"); + ThrowUserError("invalid_product_name", + { product => $product }); } # Set cookies @@ -230,8 +230,8 @@ if ($::FORM{'keywords'} && UserInGroup("editbugs")) { } my $i = GetKeywordIdFromName($keyword); if (!$i) { - $vars->{'keyword'} = $keyword; - ThrowUserError("unknown_keyword"); + ThrowUserError("unknown_keyword", + { keyword => $keyword }); } if (!$keywordseen{$i}) { push(@keywordlist, $i); @@ -301,8 +301,10 @@ if (UserInGroup("editbugs") && defined($::FORM{'dependson'})) { foreach my $i (@isect) { $both = $both . GetBugLink($i, "#" . $i) . " "; } - $vars->{'both'} = $both; - ThrowUserError("dependency_loop_multi", undef, "abort"); + + ThrowUserError("dependency_loop_multi", + { both => $both }, + "abort"); } } my $tmp = $me; @@ -337,8 +339,8 @@ if (UserInGroup(Param("timetrackinggroup")) && if ($est_time =~ /^(?:\d+(?:\.\d*)?|\.\d+)$/) { $sql .= SqlQuote($est_time) . "," . SqlQuote($est_time); } else { - $vars->{'field'} = "estimated_time"; - ThrowUserError("need_positive_number"); + ThrowUserError("need_positive_number", + { field => 'estimated_time' }); } } else { $sql .= "0, 0"; diff --git a/process_bug.cgi b/process_bug.cgi index 9476b7d68..53e8f77d6 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -223,7 +223,12 @@ if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct) $vars->{'oldvalue'} = $::oldproduct; $vars->{'newvalue'} = $::FORM{'product'}; $vars->{'field'} = 'product'; - ThrowUserError("illegal_change", undef, "abort"); + ThrowUserError("illegal_change", + { oldvalue => $::oldproduct, + newvalue => $::FORM{'product'}, + field => 'product', + }, + "abort"); } CheckFormField(\%::FORM, 'product', \@::legal_product); @@ -689,7 +694,7 @@ if (Param("usebugaliases") && defined($::FORM{'alias'})) { # Make sure the alias is unique. my $escaped_alias = SqlQuote($alias); - $vars->{'alias'} = $alias; + my $vars = { alias => $alias }; SendSQL("SELECT bug_id FROM bugs WHERE alias = $escaped_alias " . "AND bug_id != $idlist[0]"); @@ -697,17 +702,17 @@ if (Param("usebugaliases") && defined($::FORM{'alias'})) { if ($id) { $vars->{'bug_link'} = GetBugLink($id, "Bug $id"); - ThrowUserError("alias_in_use"); + ThrowUserError("alias_in_use", $vars); } # Make sure the alias isn't just a number. if ($alias =~ /^\d+$/) { - ThrowUserError("alias_is_numeric"); + ThrowUserError("alias_is_numeric", $vars); } # Make sure the alias has no commas or spaces. if ($alias =~ /[, ]/) { - ThrowUserError("alias_has_comma_or_space"); + ThrowUserError("alias_has_comma_or_space", $vars); } } @@ -750,8 +755,8 @@ if (UserInGroup(Param('timetrackinggroup'))) { DoComma(); $::query .= "$field = " . SqlQuote($er_time); } else { - $vars->{'field'} = $field; - ThrowUserError("need_positive_number"); + ThrowUserError("need_positive_number", + field => $field); } } } @@ -946,8 +951,8 @@ SWITCH: for ($::FORM{'knob'}) { SendSQL("SELECT bug_id FROM bugs where bug_id = " . SqlQuote($checkid)); $checkid = FetchOneColumn(); if (!$checkid) { - $vars->{'bug_id'} = $checkid; - ThrowUserError("invalid_bug_id"); + ThrowUserError("invalid_bug_id", + { bug_id => $checkid }); } $::FORM{'comment'} .= "\n\n*** This bug has been marked as a duplicate of $num ***"; $duplicate = $num; @@ -975,8 +980,8 @@ if ($::FORM{'keywords'}) { } my $i = GetKeywordIdFromName($keyword); if (!$i) { - $vars->{keyword} = $keyword; - ThrowUserError("unknown_keyword"); + ThrowUserError("unknown_keyword", + { keyword => $keyword }); } if (!$keywordseen{$i}) { push(@keywordlist, $i); @@ -1098,6 +1103,7 @@ foreach my $id (@idlist) { if (exists $::FORM{$col}) { if (!CheckCanChangeField($col, $id, $oldvalues[$i], $::FORM{$col})) { # More fun hacking... don't display component_id + my $vars; if ($col eq 'component_id') { $vars->{'oldvalue'} = get_component_name($oldhash{'component_id'}); $vars->{'newvalue'} = $::FORM{'component'}; @@ -1108,23 +1114,23 @@ foreach my $id (@idlist) { $vars->{'newvalue'} = $::FORM{$col}; $vars->{'field'} = $col; } - ThrowUserError("illegal_change", undef, "abort"); + ThrowUserError("illegal_change", $vars, "abort"); } } $i++; } $oldhash{'product'} = get_product_name($oldhash{'product_id'}); if (!CanEditProductId($oldhash{'product_id'})) { - $vars->{'product'} = $oldhash{'product'}; - ThrowUserError("product_edit_denied"); + ThrowUserError("product_edit_denied", + { product => $oldhash{'product'} }); } if (defined $::FORM{'product'} && $::FORM{'product'} ne $::FORM{'dontchange'} && $::FORM{'product'} ne $oldhash{'product'} && !CanEnterProduct($::FORM{'product'})) { - $vars->{'product'} = $::FORM{'product'}; - ThrowUserError("entry_access_denied"); + ThrowUserError("entry_access_denied", + { product => $::FORM{'product'} }); } if ($requiremilestone) { my $value = $::FORM{'target_milestone'}; @@ -1135,8 +1141,9 @@ foreach my $id (@idlist) { SqlQuote($oldhash{'product'})); if ($value eq FetchOneColumn()) { SendSQL("UNLOCK TABLES"); - $vars->{'bug_id'} = $id; - ThrowUserError("milestone_required", undef, "abort"); + ThrowUserError("milestone_required", + { bug_id => $id }, + "abort"); } } if (defined $::FORM{'delta_ts'} && $::FORM{'delta_ts'} ne $delta_ts) { @@ -1213,9 +1220,10 @@ foreach my $id (@idlist) { foreach my $i (@isect) { $both = $both . GetBugLink($i, "#" . $i) . " "; } - - $vars->{'both'} = $both; - ThrowUserError("dependency_loop_multi", undef, "abort"); + + ThrowUserError("dependency_loop_multi", + { both => $both }, + "abort"); } } my $tmp = $me; diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index a89d029eb..fe1d9e223 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -34,14 +34,7 @@ [% DEFAULT title = "Error" %] [% error_message = BLOCK %] - [% IF error == "aaa_example_error_tag" %] - [% title = "Example Error" %] - This is an example error. The title is set above. This text is the body - of the error. It can contain arbitrary <b>HTML</b>, and also references - to any [% parameters %] which you may have set before calling - ThrowUserError. - - [% ELSIF error == "account_creation_disabled" %] + [% IF error == "account_creation_disabled" %] [% title = "Account Creation Disabled" %] Account self-creation has been disabled or restricted. <hr> @@ -159,7 +152,7 @@ [% title = "Nice Try..." %] Nice try, [% user.login FILTER html %], but it doesn't really make sense to mark a bug as a duplicate of itself, - does it? + does it? [% ELSIF error == "email_change_in_progress" %] [% title = "Email Change Already In Progress" %] @@ -207,7 +200,7 @@ [% ELSIF error == "flag_type_sortkey_invalid" %] [% title = "Flag Type Sort Key Invalid" %] The sort key must be an integer between 0 and 32767 inclusive. - It cannot be <em>[% variables.sortkey %]</em>. + It cannot be <em>[% sortkey FILTER html %]</em>. [% ELSIF error == "illegal_at_least_x_votes" %] [% title = "Your Query Makes No Sense" %] @@ -217,6 +210,10 @@ [% ELSIF error == "illegal_attachment_edit" %] [% title = "Unauthorised Action" %] You are not authorised to edit attachment [% attach_id %]. + + [% ELSIF error == "illegal_attachment_edit_bug" %] + [% title = "Unauthorised Action" %] + You are not authorised to edit attachments on bug [% bug_id %]. [% ELSIF error == "illegal_attachment_is_patch" %] [% title = "Your Query Makes No Sense" %] @@ -507,18 +504,6 @@ [% title = "Access Denied" %] You do not have the permissions necessary to view reports for this product. - [% ELSIF error == "requestee_too_short" %] - [% title = "Requestee Name Too Short" %] - One or two characters match too many users, so please enter at least - three characters of the name/email address of the user you want to set - the flag. - - [% ELSIF error == "requestee_too_many_matches" %] - [% title = "Requestee String Matched Too Many Times" %] - The string <em>[% requestee FILTER html %]</em> matched more than - 100 users. Enter more of the name to bring the number of matches - down to a reasonable amount. - [% ELSIF error == "require_component" %] [% title = "Component Needed" %] You must choose a component to file this bug in. If necessary, @@ -569,7 +554,7 @@ [% ELSIF error == "unknown_tab" %] [% title = "Unknown Tab" %] - <code>[% current_tab_name FILTER html %]</code> is not a legal tab name. + <code>[% current_tab_name FILTER html %]</code> is not a legal tab name. [% ELSIF error == "votes_must_be_nonnegative" %] [% title = "Votes Must Be Non-negative" %] @@ -593,14 +578,13 @@ [% ELSIF error == "zero_length_file" %] [% title = "File Is Empty" %] - The file you are trying to attach is empty! + The file you are trying to attach is empty! [% ELSE %] - [%# Cope with legacy calling convention, where "error" was the string - # to print. - #%] - - [% error %] + [% title = "Error string not found" %] + The user error string <code>[% error FILTER html %]</code> was not found. + Please send email to [% Param("maintainer") %] describing the steps taken + to obtain this message. [% END %] [% END %] @@ -231,9 +231,9 @@ sub changeEmail { # The new email address should be available as this was # confirmed initially so cancel token if it is not still available if (! ValidateNewUser($new_email,$old_email)) { - $vars->{'email'} = $new_email; + $vars->{'email'} = $new_email; # Needed for Token::Cancel's mail Token::Cancel($::token,"account_exists"); - ThrowUserError("account_exists"); + ThrowUserError("account_exists", { email => $new_email } ); } # Update the user's login name in the profiles table and delete the token diff --git a/userprefs.cgi b/userprefs.cgi index 156c6a2dd..fa340f50f 100755 --- a/userprefs.cgi +++ b/userprefs.cgi @@ -385,7 +385,8 @@ SWITCH: for ($current_tab_name) { DoPermissions(); last SWITCH; }; - ThrowUserError("current_tab_name"); + ThrowUserError("unknown_tab", + { current_tab_name => $current_tab_name }); } # Generate and return the UI (HTML page) from the appropriate template. |