Re: Patch lint for grep { /.../ } and grep /.../,
[p5sagit/p5-mst-13.2.git] / lib / CGI / Carp.pm
CommitLineData
54310121 1package CGI::Carp;
2
3=head1 NAME
4
5B<CGI::Carp> - CGI routines for writing to the HTTPD (or other) error log
6
7=head1 SYNOPSIS
8
9 use CGI::Carp;
10
11 croak "We're outta here!";
12 confess "It was my fault: $!";
13 carp "It was your fault!";
14 warn "I'm confused";
15 die "I'm dying.\n";
16
71f3e297 17 use CGI::Carp qw(cluck);
18 cluck "I wouldn't do that if I were you";
19
20 use CGI::Carp qw(fatalsToBrowser);
21 die "Fatal error messages are now sent to browser";
22
54310121 23=head1 DESCRIPTION
24
25CGI scripts have a nasty habit of leaving warning messages in the error
26logs that are neither time stamped nor fully identified. Tracking down
27the script that caused the error is a pain. This fixes that. Replace
28the usual
29
30 use Carp;
31
32with
33
34 use CGI::Carp
35
36And the standard warn(), die (), croak(), confess() and carp() calls
37will automagically be replaced with functions that write out nicely
38time-stamped messages to the HTTP server error log.
39
40For example:
41
42 [Fri Nov 17 21:40:43 1995] test.pl: I'm confused at test.pl line 3.
43 [Fri Nov 17 21:40:43 1995] test.pl: Got an error message: Permission denied.
44 [Fri Nov 17 21:40:43 1995] test.pl: I'm dying.
45
46=head1 REDIRECTING ERROR MESSAGES
47
48By default, error messages are sent to STDERR. Most HTTPD servers
49direct STDERR to the server's error log. Some applications may wish
50to keep private error logs, distinct from the server's error log, or
51they may wish to direct error messages to STDOUT so that the browser
52will receive them.
53
54The C<carpout()> function is provided for this purpose. Since
55carpout() is not exported by default, you must import it explicitly by
56saying
57
58 use CGI::Carp qw(carpout);
59
60The carpout() function requires one argument, which should be a
61reference to an open filehandle for writing errors. It should be
62called in a C<BEGIN> block at the top of the CGI application so that
63compiler errors will be caught. Example:
64
65 BEGIN {
66 use CGI::Carp qw(carpout);
67 open(LOG, ">>/usr/local/cgi-logs/mycgi-log") or
68 die("Unable to open mycgi-log: $!\n");
69 carpout(LOG);
70 }
71
72carpout() does not handle file locking on the log for you at this point.
73
ba056755 74The real STDERR is not closed -- it is moved to CGI::Carp::SAVEERR. Some
54310121 75servers, when dealing with CGI scripts, close their connection to the
ba056755 76browser when the script closes STDOUT and STDERR. CGI::Carp::SAVEERR is there to
54310121 77prevent this from happening prematurely.
78
79You can pass filehandles to carpout() in a variety of ways. The "correct"
80way according to Tom Christiansen is to pass a reference to a filehandle
81GLOB:
82
83 carpout(\*LOG);
84
85This looks weird to mere mortals however, so the following syntaxes are
86accepted as well:
87
88 carpout(LOG);
89 carpout(main::LOG);
90 carpout(main'LOG);
91 carpout(\LOG);
92 carpout(\'main::LOG');
93
94 ... and so on
95
424ec8fa 96FileHandle and other objects work as well.
97
54310121 98Use of carpout() is not great for performance, so it is recommended
99for debugging purposes or for moderate-use applications. A future
100version of this module may delay redirecting STDERR until one of the
101CGI::Carp methods is called to prevent the performance hit.
102
103=head1 MAKING PERL ERRORS APPEAR IN THE BROWSER WINDOW
104
55b5d700 105If you want to send fatal (die, confess) errors to the browser, ask to
54310121 106import the special "fatalsToBrowser" subroutine:
107
108 use CGI::Carp qw(fatalsToBrowser);
109 die "Bad error here";
110
111Fatal errors will now be echoed to the browser as well as to the log. CGI::Carp
112arranges to send a minimal HTTP header to the browser so that even errors that
113occur in the early compile phase will be seen.
114Nonfatal errors will still be directed to the log file only (unless redirected
115with carpout).
116
55b5d700 117Note that fatalsToBrowser does B<not> work with mod_perl version 2.0
118and higher.
119
424ec8fa 120=head2 Changing the default message
121
122By default, the software error message is followed by a note to
123contact the Webmaster by e-mail with the time and date of the error.
124If this message is not to your liking, you can change it using the
125set_message() routine. This is not imported by default; you should
126import it on the use() line:
127
128 use CGI::Carp qw(fatalsToBrowser set_message);
129 set_message("It's not a bug, it's a feature!");
130
131You may also pass in a code reference in order to create a custom
132error message. At run time, your code will be called with the text
133of the error message that caused the script to die. Example:
134
135 use CGI::Carp qw(fatalsToBrowser set_message);
136 BEGIN {
137 sub handle_errors {
138 my $msg = shift;
139 print "<h1>Oh gosh</h1>";
b2d0d414 140 print "<p>Got an error: $msg</p>";
424ec8fa 141 }
142 set_message(\&handle_errors);
143 }
144
145In order to correctly intercept compile-time errors, you should call
146set_message() from within a BEGIN{} block.
147
6b4ac661 148=head1 MAKING WARNINGS APPEAR AS HTML COMMENTS
149
150It is now also possible to make non-fatal errors appear as HTML
151comments embedded in the output of your program. To enable this
152feature, export the new "warningsToBrowser" subroutine. Since sending
153warnings to the browser before the HTTP headers have been sent would
154cause an error, any warnings are stored in an internal buffer until
155you call the warningsToBrowser() subroutine with a true argument:
156
157 use CGI::Carp qw(fatalsToBrowser warningsToBrowser);
158 use CGI qw(:standard);
159 print header();
160 warningsToBrowser(1);
161
162You may also give a false argument to warningsToBrowser() to prevent
163warnings from being sent to the browser while you are printing some
164content where HTML comments are not allowed:
165
166 warningsToBrowser(0); # disable warnings
b2d0d414 167 print "<script type=\"text/javascript\"><!--\n";
6b4ac661 168 print_some_javascript_code();
b2d0d414 169 print "//--></script>\n";
6b4ac661 170 warningsToBrowser(1); # re-enable warnings
171
172Note: In this respect warningsToBrowser() differs fundamentally from
173fatalsToBrowser(), which you should never call yourself!
174
188ba755 175=head1 OVERRIDING THE NAME OF THE PROGRAM
176
177CGI::Carp includes the name of the program that generated the error or
178warning in the messages written to the log and the browser window.
179Sometimes, Perl can get confused about what the actual name of the
180executed program was. In these cases, you can override the program
181name that CGI::Carp will use for all messages.
182
183The quick way to do that is to tell CGI::Carp the name of the program
184in its use statement. You can do that by adding
185"name=cgi_carp_log_name" to your "use" statement. For example:
186
187 use CGI::Carp qw(name=cgi_carp_log_name);
188
189. If you want to change the program name partway through the program,
190you can use the C<set_progname()> function instead. It is not
191exported by default, you must import it explicitly by saying
192
193 use CGI::Carp qw(set_progname);
194
195Once you've done that, you can change the logged name of the program
196at any time by calling
197
198 set_progname(new_program_name);
199
200You can set the program back to the default by calling
201
202 set_progname(undef);
203
204Note that this override doesn't happen until after the program has
205compiled, so any compile-time errors will still show up with the
206non-overridden program name
207
54310121 208=head1 CHANGE LOG
209
2101.05 carpout() added and minor corrections by Marc Hedlund
211 <hedlund@best.com> on 11/26/95.
212
2131.06 fatalsToBrowser() no longer aborts for fatal errors within
214 eval() statements.
215
424ec8fa 2161.08 set_message() added and carpout() expanded to allow for FileHandle
217 objects.
218
2191.09 set_message() now allows users to pass a code REFERENCE for
220 really custom error messages. croak and carp are now
221 exported by default. Thanks to Gunther Birznieks for the
222 patches.
223
2241.10 Patch from Chris Dean (ctdean@cogit.com) to allow
225 module to run correctly under mod_perl.
226
71f3e297 2271.11 Changed order of &gt; and &lt; escapes.
228
2291.12 Changed die() on line 217 to CORE::die to avoid B<-w> warning.
230
2311.13 Added cluck() to make the module orthogonal with Carp.
6b4ac661 232 More mod_perl related fixes.
233
2341.20 Patch from Ilmari Karonen (perl@itz.pp.sci.fi): Added
235 warningsToBrowser(). Replaced <CODE> tags with <PRE> in
236 fatalsToBrowser() output.
71f3e297 237
b2d0d414 2381.23 ineval() now checks both $^S and inspects the message for the "eval" pattern
3c4b39be 239 (hack alert!) in order to accommodate various combinations of Perl and
b2d0d414 240 mod_perl.
241
188ba755 2421.24 Patch from Scott Gifford (sgifford@suspectclass.com): Add support
243 for overriding program name.
244
1c87da1d 2451.26 Replaced CORE::GLOBAL::die with the evil $SIG{__DIE__} because the
246 former isn't working in some people's hands. There is no such thing
247 as reliable exception handling in Perl.
248
2ed511ec 2491.27 Replaced tell STDOUT with bytes=tell STDOUT.
250
54310121 251=head1 AUTHORS
252
b2d0d414 253Copyright 1995-2002, Lincoln D. Stein. All rights reserved.
71f3e297 254
255This library is free software; you can redistribute it and/or modify
256it under the same terms as Perl itself.
54310121 257
71f3e297 258Address bug reports and comments to: lstein@cshl.org
54310121 259
260=head1 SEE ALSO
261
262Carp, CGI::Base, CGI::BasePlus, CGI::Request, CGI::MiniSvr, CGI::Form,
263CGI::Response
188ba755 264 if (defined($CGI::Carp::PROGNAME))
265 {
266 $file = $CGI::Carp::PROGNAME;
267 }
54310121 268
269=cut
270
271require 5.000;
272use Exporter;
3acbd4f5 273#use Carp;
1c87da1d 274BEGIN {
275 require Carp;
276 *CORE::GLOBAL::die = \&CGI::Carp::die;
277}
278
7f16a916 279use File::Spec;
54310121 280
281@ISA = qw(Exporter);
282@EXPORT = qw(confess croak carp);
1c87da1d 283@EXPORT_OK = qw(carpout fatalsToBrowser warningsToBrowser wrap set_message set_progname cluck ^name= die);
3538e1d5 284
54310121 285$main::SIG{__WARN__}=\&CGI::Carp::warn;
1c87da1d 286
29ddc2a4 287$CGI::Carp::VERSION = '1.29';
424ec8fa 288$CGI::Carp::CUSTOM_MSG = undef;
54310121 289
1c87da1d 290
54310121 291# fancy import routine detects and handles 'errorWrap' specially.
292sub import {
293 my $pkg = shift;
294 my(%routines);
188ba755 295 my(@name);
188ba755 296 if (@name=grep(/^name=/,@_))
297 {
298 my($n) = (split(/=/,$name[0]))[1];
299 set_progname($n);
300 @_=grep(!/^name=/,@_);
301 }
302
424ec8fa 303 grep($routines{$_}++,@_,@EXPORT);
304 $WRAP++ if $routines{'fatalsToBrowser'} || $routines{'wrap'};
6b4ac661 305 $WARN++ if $routines{'warningsToBrowser'};
54310121 306 my($oldlevel) = $Exporter::ExportLevel;
307 $Exporter::ExportLevel = 1;
308 Exporter::import($pkg,keys %routines);
309 $Exporter::ExportLevel = $oldlevel;
1c87da1d 310 $main::SIG{__DIE__} =\&CGI::Carp::die if $routines{'fatalsToBrowser'};
311# $pkg->export('CORE::GLOBAL','die');
54310121 312}
313
314# These are the originals
9014bb8e 315sub realwarn { CORE::warn(@_); }
316sub realdie { CORE::die(@_); }
54310121 317
318sub id {
319 my $level = shift;
320 my($pack,$file,$line,$sub) = caller($level);
7f16a916 321 my($dev,$dirs,$id) = File::Spec->splitpath($file);
54310121 322 return ($file,$line,$id);
323}
324
325sub stamp {
326 my $time = scalar(localtime);
327 my $frame = 0;
ac734d8b 328 my ($id,$pack,$file,$dev,$dirs);
188ba755 329 if (defined($CGI::Carp::PROGNAME)) {
330 $id = $CGI::Carp::PROGNAME;
331 } else {
332 do {
333 $id = $file;
334 ($pack,$file) = caller($frame++);
335 } until !$file;
336 }
7f16a916 337 ($dev,$dirs,$id) = File::Spec->splitpath($id);
54310121 338 return "[$time] $id: ";
339}
340
188ba755 341sub set_progname {
342 $CGI::Carp::PROGNAME = shift;
343 return $CGI::Carp::PROGNAME;
344}
345
346
54310121 347sub warn {
348 my $message = shift;
349 my($file,$line,$id) = id(1);
350 $message .= " at $file line $line.\n" unless $message=~/\n$/;
6b4ac661 351 _warn($message) if $WARN;
54310121 352 my $stamp = stamp;
353 $message=~s/^/$stamp/gm;
354 realwarn $message;
355}
356
6b4ac661 357sub _warn {
358 my $msg = shift;
359 if ($EMIT_WARNINGS) {
360 # We need to mangle the message a bit to make it a valid HTML
361 # comment. This is done by substituting similar-looking ISO
362 # 8859-1 characters for <, > and -. This is a hack.
363 $msg =~ tr/<>-/\253\273\255/;
364 chomp $msg;
365 print STDOUT "<!-- warning: $msg -->\n";
366 } else {
367 push @WARNINGS, $msg;
368 }
369}
370
6b4ac661 371
424ec8fa 372# The mod_perl package Apache::Registry loads CGI programs by calling
373# eval. These evals don't count when looking at the stack backtrace.
374sub _longmess {
375 my $message = Carp::longmess();
29ddc2a4 376 $message =~ s,eval[^\n]+(ModPerl|Apache)/(?:Registry|Dispatch)\w*\.pm.*,,s
8f3ccfa2 377 if exists $ENV{MOD_PERL};
378 return $message;
379}
380
381sub ineval {
382 (exists $ENV{MOD_PERL} ? 0 : $^S) || _longmess() =~ /eval [\{\']/m
424ec8fa 383}
384
54310121 385sub die {
13548fdf 386 my ($arg,@rest) = @_;
387 realdie ($arg,@rest) if ineval();
388
8f3ccfa2 389 if (!ref($arg)) {
13548fdf 390 $arg = join("", ($arg,@rest));
8f3ccfa2 391 my($file,$line,$id) = id(1);
392 $arg .= " at $file line $line." unless $arg=~/\n$/;
393 &fatalsToBrowser($arg) if $WRAP;
394 if (($arg =~ /\n$/) || !exists($ENV{MOD_PERL})) {
395 my $stamp = stamp;
396 $arg=~s/^/$stamp/gm;
397 }
398 if ($arg !~ /\n$/) {
399 $arg .= "\n";
400 }
401 }
402 realdie $arg;
54310121 403}
404
424ec8fa 405sub set_message {
406 $CGI::Carp::CUSTOM_MSG = shift;
407 return $CGI::Carp::CUSTOM_MSG;
408}
409
2371fea9 410sub confess { CGI::Carp::die Carp::longmess @_; }
411sub croak { CGI::Carp::die Carp::shortmess @_; }
412sub carp { CGI::Carp::warn Carp::shortmess @_; }
413sub cluck { CGI::Carp::warn Carp::longmess @_; }
54310121 414
415# We have to be ready to accept a filehandle as a reference
416# or a string.
417sub carpout {
418 my($in) = @_;
424ec8fa 419 my($no) = fileno(to_filehandle($in));
71f3e297 420 realdie("Invalid filehandle $in\n") unless defined $no;
54310121 421
422 open(SAVEERR, ">&STDERR");
423 open(STDERR, ">&$no") or
424 ( print SAVEERR "Unable to redirect STDERR: $!\n" and exit(1) );
425}
426
6b4ac661 427sub warningsToBrowser {
428 $EMIT_WARNINGS = @_ ? shift : 1;
429 _warn(shift @WARNINGS) while $EMIT_WARNINGS and @WARNINGS;
430}
431
54310121 432# headers
433sub fatalsToBrowser {
8f3ccfa2 434 my($msg) = @_;
435 $msg=~s/&/&amp;/g;
436 $msg=~s/>/&gt;/g;
437 $msg=~s/</&lt;/g;
438 $msg=~s/\"/&quot;/g;
439 my($wm) = $ENV{SERVER_ADMIN} ?
440 qq[the webmaster (<a href="mailto:$ENV{SERVER_ADMIN}">$ENV{SERVER_ADMIN}</a>)] :
441 "this site's webmaster";
442 my ($outer_message) = <<END;
424ec8fa 443For help, please send mail to $wm, giving this error message
444and the time and date of the error.
445END
8f3ccfa2 446 ;
447 my $mod_perl = exists $ENV{MOD_PERL};
8f3ccfa2 448
8f3ccfa2 449 if ($CUSTOM_MSG) {
450 if (ref($CUSTOM_MSG) eq 'CODE') {
0c45d622 451 print STDOUT "Content-type: text/html\n\n"
452 unless $mod_perl;
8f3ccfa2 453 &$CUSTOM_MSG($msg); # nicer to perl 5.003 users
454 return;
455 } else {
456 $outer_message = $CUSTOM_MSG;
424ec8fa 457 }
8f3ccfa2 458 }
1c87da1d 459
8f3ccfa2 460 my $mess = <<END;
b2d0d414 461<h1>Software error:</h1>
462<pre>$msg</pre>
463<p>
71f3e297 464$outer_message
b2d0d414 465</p>
54310121 466END
8f3ccfa2 467 ;
1c87da1d 468
8f3ccfa2 469 if ($mod_perl) {
741ff09d 470 my $r;
0a9bdad4 471 if ($ENV{MOD_PERL_API_VERSION} && $ENV{MOD_PERL_API_VERSION} == 2) {
8f3ccfa2 472 $mod_perl = 2;
741ff09d 473 require Apache2::RequestRec;
474 require Apache2::RequestIO;
475 require Apache2::RequestUtil;
8f3ccfa2 476 require APR::Pool;
477 require ModPerl::Util;
741ff09d 478 require Apache2::Response;
479 $r = Apache2::RequestUtil->request;
480 }
481 else {
482 $r = Apache->request;
8f3ccfa2 483 }
8f3ccfa2 484 # If bytes have already been sent, then
485 # we print the message out directly.
486 # Otherwise we make a custom error
487 # handler to produce the doc for us.
488 if ($r->bytes_sent) {
489 $r->print($mess);
490 $mod_perl == 2 ? ModPerl::Util::exit(0) : $r->exit;
71f3e297 491 } else {
1c87da1d 492 # MSIE won't display a custom 500 response unless it is >512 bytes!
8f3ccfa2 493 if ($ENV{HTTP_USER_AGENT} =~ /MSIE/) {
1c87da1d 494 $mess = "<!-- " . (' ' x 513) . " -->\n$mess";
8f3ccfa2 495 }
1c87da1d 496 $r->custom_response(500,$mess);
71f3e297 497 }
8f3ccfa2 498 } else {
2ed511ec 499 my $bytes_written = eval{tell STDOUT};
500 if (defined $bytes_written && $bytes_written > 0) {
0c45d622 501 print STDOUT $mess;
502 }
503 else {
504 print STDOUT "Content-type: text/html\n\n";
505 print STDOUT $mess;
506 }
8f3ccfa2 507 }
13548fdf 508
509 warningsToBrowser(1); # emit warnings before dying
424ec8fa 510}
511
512# Cut and paste from CGI.pm so that we don't have the overhead of
513# always loading the entire CGI module.
514sub to_filehandle {
515 my $thingy = shift;
516 return undef unless $thingy;
517 return $thingy if UNIVERSAL::isa($thingy,'GLOB');
518 return $thingy if UNIVERSAL::isa($thingy,'FileHandle');
519 if (!ref($thingy)) {
520 my $caller = 1;
521 while (my $package = caller($caller++)) {
522 my($tmp) = $thingy=~/[\':]/ ? $thingy : "$package\:\:$thingy";
523 return $tmp if defined(fileno($tmp));
524 }
525 }
526 return undef;
54310121 527}
528
5291;