I have some mod_perl-2 software which keeps causing the Apache server to
crash, and I believe the cause of it is users pressing the Stop button
in their browsers, causing the pipe to be broken, which then leads to
the crash when CGI::Carp's fatalsToBrowser feature tries to send an HTML
error message to the browser (... saying that data can't be sent to the
client!!!).

I want to catch the "broken pipe" error and simply log it in the
error.log, and rethrow other exceptions (to be picked up by CGI::Carp's
fatalsToBrowser), but instead of getting an APR::Error object, I'm
getting a string saying "APR does not understand this error code"

The following program (running via ModPerl::Registry) reproduces the
problem:

use strict;
use warnings;
BEGIN {
    require CGI::Carp;
    CGI::Carp->import(qw(fatalsToBrowser));
    CGI::Carp::set_message(' ');
}
print "Content-Type: text/plain\n\n";
print '-' x 80, "\n" while (1);

Set the program running, then press Stop in the web browser. The Apache
server crashes (usually just the child exiting with status 9, and the
parent spawns a new one, but occasionally the whole thing seems to abort
with status 2) with this in the error.log:

[Wed Dec 08 18:07:02 2010] [info] [client 10.23.100.22] (OS 10054)An
existing connection was forcibly closed by the remote host.  :
core_output_filter: writing data to the network
:Apache2 IO flush: (620018) APR does not understand this error code at
-e line 0[Wed Dec 08 18:07:02 2010] [notice] Parent: child process
exited with status 9 -- Restarting.

If I change the last two lines of code to:

my $ok = eval {
    print "Content-Type: text/plain\n\n";
    print '-' x 80, "\n" while (1);
};
if (not defined $ok) {
    if ($@) {
        if (ref $@) {
            printf STDERR "Caught an %s: %s\n", ref($@), $@;
        }
        else {
            printf STDERR "Caught a string: %s\n", $@;
        }
    }
    else {
        printf STDERR "Unexpected\n";
    }
}

then it no longer crashes. The error is simply caught and logged to
error.log, which now says:

[Wed Dec 08 18:23:35 2010] [info] [client 10.23.100.22] (OS 10054)An
existing connection was forcibly closed by the remote host.  :
core_output_filter: writing data to the network
Caught a string: APR does not understand this error code at
C:/Radview/apache/cgi-bin/problem.pl line 12.

However, I want to only do that in certain cases where a useful HTML
error message can't be written back to the browser, but (as seen above)
$@ is a fairly useless string (not even with the "(620018)" bit that
Apache normally logs) instead of the useful APR::Error object that I was
hoping for.

What's gone wrong here and/or is there some other way of handling this
situation (which works on Win32!)?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@perl.apache.org
For additional commands, e-mail: dev-h...@perl.apache.org

Reply via email to