Ævar Arnfjörð Bjarmason wrote on 2012-10-16:
> On Wed, Apr 25, 2012 at 9:29 PM, Fred Moyer <[email protected]> wrote:
>
> When mod_perl 2.0.6 was released this is one of the things that was
> changed:
>
>> PerlIOApache_flush() and mpxs_Apache2__RequestRec_rflush() now no
>> longer throw exceptions when modperl_wbucket_flush() fails if the
>> failure was just a reset connection or an aborted connection. The
>> failure is simply logged to the error log instead. This should fix
>> cases of httpd.exe crashing when users press the Stop button in their
>> web browsers. [Steve Hay]
>
> And this is the relevant commit:
> http://mail-archives.apache.org/mod_mbox/perl-modperl-
> cvs/201105.mbox/%[email protected]%3E
>
> I maintain an application where we logged these rflush and print
> errors ourselves
[...]
> It seems to me that after mod_perl 2.0.6 we'll lose this ability to
> log these errors, and our server error logs will start to be mostly
> the result of the new ap_log_error() call added in 2.0.6.
>
> So my questions are:
>
> * Is there some better way that I've missed to hook into
> ap_log_error() like I'm doing with
> warn_only_on_certain_apache_errors() now so I can still log when
> these things happen.
> * Was this really needed in the first place given that you can quite
> easily just subclass the request object and provide your own
> print/rflush if you'd like to catch these?
>
> Even if there's some way to hook into the Apache error log printing
> mechanism I think just doing croak() and allowing you to catch it
> by writing your own subclass is a more elegant and Perl-like
> interface.
I made this change because of persistent problems reported by several of our
customers, and also reported by others on the modperl lists, regarding the
Apache server crashing due to uncaught exceptions.
Note that exceptions thrown by various print()/write() functions were not
changed. Needing to catch these is perfectly normal, and these are still thrown
exactly as before and can still be caught and logged or whatever as usual. It
is only the more elusive flush() exceptions which were downgraded into error
log calls. One doesn't normally call flush() explicitly, and I was never able
to reproduce the flush exceptions reported by our customers when testing, but
they kept coming up in log files as the cause of the crash.
In our case, most of our software is legacy code migrated from a CGI
environment, and is run via ModPerl::RegistryCooker. Each script does
everything within an eval{} and successfully catches and handles (in
ModPerl::RegistryCooker::error_check()) the occasional print() exception, but
the flush() exceptions which occurred from time to time in the wild always
escaped this exception trap.
So that is why I changed the flush() exceptions into error logs. Note that SVN
revision 202146 (way back in 2005) already did the same thing for filter
flushing.
I hope you will find that your server error logs do not fill up with the new
ap_log_error() calls: your own print() method will still catch print()
exceptions as before; it's only the flush() errors that will now go straight to
the Apache error log. I'm sorry, I don't know how you can intercept those
ap_log_error() calls.
However, I would not be entirely averse to reverting the change if you can see
how to catch the seemingly uncatchable flush errors when running via
ModPerl::RegistryCooker (and also come up with some way of triggering them in
the first place so that I can test it!).
Please also see the following two threads if you haven't already for more
background on the change:
http://www.gossamer-threads.com/lists/modperl/modperl/102958
http://www.gossamer-threads.com/lists/modperl/dev/102983