X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FCGI%2FCarp.pm;h=9b67d76d009beaf5cee1abd4c8167492cf87abfc;hb=424ec8fa43885c75adde62690957af43a6537c02;hp=4cd79467fd8ce7fac02cdc8a7005992fe275d25a;hpb=eab60bb1f2e96e200fbded3694574d80930d568e;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/CGI/Carp.pm b/lib/CGI/Carp.pm index 4cd7946..9b67d76 100644 --- a/lib/CGI/Carp.pm +++ b/lib/CGI/Carp.pm @@ -87,6 +87,8 @@ accepted as well: ... and so on +FileHandle and other objects work as well. + Use of carpout() is not great for performance, so it is recommended for debugging purposes or for moderate-use applications. A future version of this module may delay redirecting STDERR until one of the @@ -106,6 +108,34 @@ occur in the early compile phase will be seen. Nonfatal errors will still be directed to the log file only (unless redirected with carpout). +=head2 Changing the default message + +By default, the software error message is followed by a note to +contact the Webmaster by e-mail with the time and date of the error. +If this message is not to your liking, you can change it using the +set_message() routine. This is not imported by default; you should +import it on the use() line: + + use CGI::Carp qw(fatalsToBrowser set_message); + set_message("It's not a bug, it's a feature!"); + +You may also pass in a code reference in order to create a custom +error message. At run time, your code will be called with the text +of the error message that caused the script to die. Example: + + use CGI::Carp qw(fatalsToBrowser set_message); + BEGIN { + sub handle_errors { + my $msg = shift; + print "

Oh gosh

"; + print "Got an error: $msg"; + } + set_message(\&handle_errors); + } + +In order to correctly intercept compile-time errors, you should call +set_message() from within a BEGIN{} block. + =head1 CHANGE LOG 1.05 carpout() added and minor corrections by Marc Hedlund @@ -114,6 +144,17 @@ with carpout). 1.06 fatalsToBrowser() no longer aborts for fatal errors within eval() statements. +1.08 set_message() added and carpout() expanded to allow for FileHandle + objects. + +1.09 set_message() now allows users to pass a code REFERENCE for + really custom error messages. croak and carp are now + exported by default. Thanks to Gunther Birznieks for the + patches. + +1.10 Patch from Chris Dean (ctdean@cogit.com) to allow + module to run correctly under mod_perl. + =head1 AUTHORS Lincoln D. Stein . Feel free to redistribute @@ -133,18 +174,19 @@ use Carp; @ISA = qw(Exporter); @EXPORT = qw(confess croak carp); -@EXPORT_OK = qw(carpout fatalsToBrowser); +@EXPORT_OK = qw(carpout fatalsToBrowser wrap set_message); $main::SIG{__WARN__}=\&CGI::Carp::warn; $main::SIG{__DIE__}=\&CGI::Carp::die; -$CGI::Carp::VERSION = '1.06'; +$CGI::Carp::VERSION = '1.10'; +$CGI::Carp::CUSTOM_MSG = undef; # fancy import routine detects and handles 'errorWrap' specially. sub import { my $pkg = shift; my(%routines); - grep($routines{$_}++,@_); - $WRAP++ if $routines{'fatalsToBrowser'}; + grep($routines{$_}++,@_,@EXPORT); + $WRAP++ if $routines{'fatalsToBrowser'} || $routines{'wrap'}; my($oldlevel) = $Exporter::ExportLevel; $Exporter::ExportLevel = 1; Exporter::import($pkg,keys %routines); @@ -183,18 +225,32 @@ sub warn { realwarn $message; } +# The mod_perl package Apache::Registry loads CGI programs by calling +# eval. These evals don't count when looking at the stack backtrace. +sub _longmess { + my $message = Carp::longmess(); + my $mod_perl = ($ENV{'GATEWAY_INTERFACE'} + && $ENV{'GATEWAY_INTERFACE'} =~ /^CGI-Perl\//); + $message =~ s,eval[^\n]+Apache/Registry\.pm.*,,s if $mod_perl; + return( $message ); +} + sub die { my $message = shift; my $time = scalar(localtime); my($file,$line,$id) = id(1); - return undef if $file=~/^\(eval/; $message .= " at $file line $line.\n" unless $message=~/\n$/; - &fatalsToBrowser($message) if $WRAP; + &fatalsToBrowser($message) if $WRAP && _longmess() !~ /eval [{\']/m; my $stamp = stamp; $message=~s/^/$stamp/gm; realdie $message; } +sub set_message { + $CGI::Carp::CUSTOM_MSG = shift; + return $CGI::Carp::CUSTOM_MSG; +} + # Avoid generating "subroutine redefined" warnings with the following # hack: { @@ -211,14 +267,8 @@ EOF # or a string. sub carpout { my($in) = @_; - $in = $$in if ref($in); # compatability with Marc's method; - my($no) = fileno($in); - unless (defined($no)) { - my($package) = caller; - my($handle) = $in=~/[':]/ ? $in : "$package\:\:$in"; - $no = fileno($handle); - } - die "Invalid filehandle $in\n" unless $no; + my($no) = fileno(to_filehandle($in)); + die "Invalid filehandle $in\n" unless defined $no; open(SAVEERR, ">&STDERR"); open(STDERR, ">&$no") or @@ -230,13 +280,51 @@ sub fatalsToBrowser { my($msg) = @_; $msg=~s/>/>/g; $msg=~s/$ENV{SERVER_ADMIN})] : + "this site's webmaster"; + my ($outer_message) = <Software error: $msg

-Please send mail to this site's webmaster for help. +$outer_message; END + ; +} + +# Cut and paste from CGI.pm so that we don't have the overhead of +# always loading the entire CGI module. +sub to_filehandle { + my $thingy = shift; + return undef unless $thingy; + return $thingy if UNIVERSAL::isa($thingy,'GLOB'); + return $thingy if UNIVERSAL::isa($thingy,'FileHandle'); + if (!ref($thingy)) { + my $caller = 1; + while (my $package = caller($caller++)) { + my($tmp) = $thingy=~/[\':]/ ? $thingy : "$package\:\:$thingy"; + return $tmp if defined(fileno($tmp)); + } + } + return undef; } 1;