Or, why is the script sending two headers?
# minimum code to illustrate point # based on example in 'CGI programming with Perl' use CGI; use CGI::Carp qw( fatalsToBrowser set_message ); $CGI::HEADERS_ONCE = 1; BEGIN { sub carp_error { my $message = shift; error( $message ) } CGI::Carp::set_message( \&carp_error ) } my $q = new CGI; # time passes # the next line wouldn't cause a duplicate header # die; print $q->header( 'text/html' ); # this next line would # die; # send the broswer a message print "test"; exit; sub error{ # die nicely exit }

The reason is clear and easily available in the docs, perlmonks and many books that I have. It still took me a long time to work out! I hope this may help others.

1. HEADERS_ONCE applies to each CGI query object.
2. set_message always sends a header.

So depending on when the error occurs the browser may or may not display an unwanted content header. That is, if the error occurs before or after this line:

print $q->header( 'text/html' );

Conclusion?
The excellent "CGI programming with Perl" says this is "one of the biggest challenges for catching errors". Sadly, I had the same problem with the solution it offers. I'm not up to small challenges never mind big ones! So, I only use CGI::Carp during debugging.

Out of intrest, I identified the error I was chasing by studying the access log. I was relying on $ENV{HTTP_REFERER} to identify which page had called the script.
I've seen this suggested on perlmonks in answer to a question about maintaining state. But again, the docs always say 'not all browsers support this' (and did I take any notice!).
The script was throwing 500 errors because HTTP_REFERER was '' (blank).
I have a robot.txt telling robots to ignore my script folder.
While I ponder what to do I am trapping the condition and saying 'service temporarily unavailable'!
I'm considering using javascript to send the file name appended as a query. It's a simple 'printer friendly' script and the link appears on 1k pages. Weep.

In case anyone asks I have a day job (although I did get a bottle of scotch at xmas) and I haven't done any homework since 1973!

First post - hope this is ok
wfsp
update: tried to make the code clearer

Replies are listed 'Best First'.
Re: Why is the browser displaying a content header?
by ercparker (Hermit) on Jul 05, 2004 at 13:40 UTC
    using the example code you provided (modified a little adding a couple semi-colons where needed
    and some text to print
    it's not displaying the content header in the browser for me on a Mac using Safari or IE
    #!/usr/bin/perl use CGI; use CGI::Carp qw(fatalsToBrowser set_message); $CGI::HEADERS_ONCE = 1; BEGIN { sub carp_error { my $message = shift; error( $message ); } CGI::Carp::set_message( \&carp_error ); } my $q = new CGI; # time passes print $q->header( 'text/html' ); print "test"; exit; sub error{ # die nicely exit; }
      Hi, Try it with a
      die; # induce a fatal error
      1. Before the print header and
      2. After the print header.
      Sorry I didn't make that clear. Thanks for your trouble,
      wfsf
Re: Why is the browser displaying a content header?
by davido (Cardinal) on Jul 05, 2004 at 15:28 UTC

    The workaround I found was to have my &carpout() function not only print a message, but also set a flag also available to my main script. Then before printing a CGI header in the main portion I just check to see if the error flag has been set, and if so, suppress printing an additional header.

    I dislike using flags too often, but this is a case where that solution seems to work out ok.


    Dave

      Good idea. I also found that putting the 'regular' output to the browser at the end of the main script minimised the problem. I've seen this recommended for other reasons.
      Also, to exit from &carpout. You can end up with two messages as well as duplicate headers (one message saying 'success' and another saying 'fail')!
      Many thanks, wfsp.