[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