@matheusbsbs / matheus-bagliano / commits / 7a59745710
Fork 0

gitweb: Add custom error handler using die_error

Change the default message for errors (for fatalsToBrowser) to use die_error() subroutine. This way errors (and explicitely calling 'die MESSAGE') would generate 'Internal Server Error' error message. Note that call to set_message is intentionally not put in BEGIN block; we set error handler to use die_error() only after we are sure that we can use it, after all needed variables are set. Due to the fact that error handler set via set_message() subroutine from CGI::Carp (in the fatalsToBrowser case) is called after HTTP headers were already printed (with exception of MOD_PERL), gitweb cannot return 'Status: 500 Internal Server Error'. Thanks to the fact that die_error() no longer uses 'exit', errors would be logged by CGI::Carp, independent on whether default error handler is used, or handle_errors_html which uses die_error is used. Signed-off-by: Jakub Narebski <jnareb@gmail.com> Acked-by: Petr Baudis <pasky@suse.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jakub Narebski committed Apr 24, 2010 at 16:00 UTC 7a59745710e964f9498f37a3184bf95b9b4a772b
1 file changed +23 -4
gitweb/gitweb.perl
+23 -4
@@ -11,7 +11,7 @@ use strict;
11 use warnings;
12 use CGI qw(:standard :escapeHTML -nosticky);
13 use CGI::Util qw(unescape);
14 -use CGI::Carp qw(fatalsToBrowser);
14 +use CGI::Carp qw(fatalsToBrowser set_message);
15 use Encode;
16 use Fcntl ':mode';
17 use File::Find qw();
@@ -952,6 +952,21 @@ if ($git_avatar eq 'gravatar') {
952 $git_avatar = '';
953 }
954
955 +# custom error handler: 'die <message>' is Internal Server Error
956 +sub handle_errors_html {
957 + my $msg = shift; # it is already HTML escaped
958 +
959 + # to avoid infinite loop where error occurs in die_error,
960 + # change handler to default handler, disabling handle_errors_html
961 + set_message("Error occured when inside die_error:\n$msg");
962 +
963 + # you cannot jump out of die_error when called as error handler;
964 + # the subroutine set via CGI::Carp::set_message is called _after_
965 + # HTTP headers are already written, so it cannot write them itself
966 + die_error(undef, undef, $msg, -error_handler => 1, -no_http_header => 1);
967 +}
968 +set_message(\&handle_errors_html);
969 +
970 # dispatch
971 if (!defined $action) {
972 if (defined $hash) {
@@ -3167,6 +3182,7 @@ sub blob_contenttype {
3182 sub git_header_html {
3183 my $status = shift || "200 OK";
3184 my $expires = shift;
3185 + my %opts = @_;
3186
3187 my $title = "$site_name";
3188 if (defined $project) {
@@ -3194,7 +3210,8 @@ sub git_header_html {
3210 $content_type = 'text/html';
3211 }
3212 print $cgi->header(-type=>$content_type, -charset => 'utf-8',
3197 - -status=> $status, -expires => $expires);
3213 + -status=> $status, -expires => $expires)
3214 + unless ($opts{'-no_http_headers'});
3215 my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : '';
3216 print <<EOF;
3217 <?xml version="1.0" encoding="utf-8"?>
@@ -3411,6 +3428,7 @@ sub die_error {
3428 my $status = shift || 500;
3429 my $error = esc_html(shift) || "Internal Server Error";
3430 my $extra = shift;
3431 + my %opts = @_;
3432
3433 my %http_responses = (
3434 400 => '400 Bad Request',
@@ -3419,7 +3437,7 @@ sub die_error {
3437 500 => '500 Internal Server Error',
3438 503 => '503 Service Unavailable',
3439 );
3422 - git_header_html($http_responses{$status});
3440 + git_header_html($http_responses{$status}, undef, %opts);
3441 print <<EOF;
3442 <div class="page_body">
3443 <br /><br />
@@ -3433,7 +3451,8 @@ EOF
3451 print "</div>\n";
3452
3453 git_footer_html();
3436 - goto DONE_GITWEB;
3454 + goto DONE_GITWEB
3455 + unless ($opts{'-error_handler'});
3456 }
3457
3458 ## ----------------------------------------------------------------------