[cgiapp] Errors on the browser with CGI::Application::Dispatch
Richard Jones
ra.jones at dpw.clara.co.uk
Sun Mar 8 18:34:56 EDT 2009
Michele Beltrame wrote:
> Hello all!
>
> First post on this list so... hello again. :-)
>
> I use CGI::Application::Dispatch and am wondering if there is a way to
> output errors thrown by the application to the standard output. Since I
> began using Dispatch, it just ignores CGI::Carp/fatalsToBrowser/ and any
> other thing I try, and just prints errors in the web server error log.
>
> Not that big issue, but can error reporting on the browser be enabled?
> I'm not looking for logging or so, but even reporting of things such as
> *compilation* errors.
>
Hi Michele, welcome to the list!
I see no-one more knowledgeable than me has replied so far, so I'll
illustrate how I handle this situation. In my Dispatch sub-class I load
an error handler that overrides $SIG{__DIE__} to trap the error and
display it in the browser, optionally sending the nominated admin an
e-mail alert:
#--------------------------------------------------
package MyApp::Dispatch;
BEGIN {
use MyApp::Local::ErrorHandler;
}
#--------------------------------------------------
package MyApp::Local::ErrorHandler;
$|++;
BEGIN {
use POSIX qw(strftime);
use Mail::Sendmail; # or equivalent
$SIG{__DIE__} = \&fatal_error;
}
sub fatal_error {
my $message = shift;
my $incident = unpack "H*", pack "NS", time, $$;
my $time = strftime "%d-%b-%Y %H:%M:%S", localtime;
my %report = (
incident => $incident,
message => $message,
);
# record reason for death in the error log:
warn join "", map {
sprintf "crash %s [%s]: %s\n", $incident, $time, $_;
} split /\n+/, $message;
# alert admin:
send_email(\%report);
# now give the user a place to record their experience
print sub_that_outputs_nice_html(\%report);
exit 0 unless $ENV{MOD_PERL}; # keeps the script from generating
# a 500 error, but kills the CA:Server
}
It's actually based on an article by Randal Schwartz called "Safe CGI
Death" (http://www.stonehenge.com/merlyn/PerlJournal/col05.html).
But be warned, I've had *many* difficulties with this approach in a
persistent environment (the original article probably didn't intend it
to be used in that capacity), and there are several plugins that just
won't play nice with $SIG{__DIE__} handlers, the most recent one I've
had to eliminate is CAP::Redirect. See an earlier thread for some more
examples of grief with custom die handlers.
I think $SIG{__DIE__} handlers in general are tricky to get working
properly (at least in persistent envs - see some of Rons previous
articles), and I've not yet found a way to make it work reliably under
mod_perl (though most of my work so far has been devel under
CA::Server). But it *is* one way to produce nice end-user feedback for
internal errors that otherwise produce the not very user-friendly
"CGI::Application::Dispatch error! Internal Server Error" page.
Would be interested to hear how others have handled this situation though.
--
Richard Jones
More information about the cgiapp
mailing list