fireartist has asked for the wisdom of the Perl Monks concerning the following question:

In my last large CGI application, I had a sub 'print_error' defined in a module 'Shop.pm'.
I sent any fatal errors to that, e.g.
$sth = $dbh->prepare($sql) or Shop::print_error('could not connect to DB', $DBI::errstr);
The print_error sub then used HTML::Template to send a error message to the browser, and then used sendmail to send an error report to the admin.

A lot of the code was just error checking.
Due to my laziness, I'd like to cut out all of the error checking, of course.
I'm thinking I could use DBI's {RaiseError} and use Fatal to catch anything else that I consider die-able.
I've mocked up some psuedo-code below to give an idea of what I'm thinking.
My question is: Are there any likely problems with this approach and are there better ways of achieving this?
#!/usr/bin/perl -T use strict; use warnings; use CGI; use DBI; use HTML::Template; use Fatal qw/ open DBI::connect /; $SIG{__DIE__} = \&print_error; use My::Conf; my $conf = new My::Conf; ### main program goes here. sub print_error { eval { print CGI::header(); open (FILE, "< $conf->{'errorfile'}"); while (<FILE>) { print }; close FILE; } eval { # Use sendmail to send @_ and %ENV to admin. } 1; };
Note: My preference would be to print a CGI redirect rather than opening a file, which might fail.
However, I wouldn't know whether a header had already been printed or not. (If a header had already been printed, the redirect wouldn't work)

Replies are listed 'Best First'.
Re: custom CGI die
by shemp (Deacon) on May 22, 2003 at 20:42 UTC
    Use this descendent of CGI
    package Some_CGI; use CGI; @ISA = qw(CGI); use strict; my $is_header_printed = 0; sub header { my $self = shift; return if $is_header_printed; $is_header_printed = 1; $self->SUPER::header(); } 1;
    If you use this class instead of CGI, and call header in the object oriented sense, it should accomplish what you want.
    ... my $form = Some_CGI->new(); ... print $form->header(); ...
Re: custom CGI die
by little (Curate) on May 24, 2003 at 11:00 UTC

    tjios is a suggestion to circumvent all those errorprone hassles ... *grin*

    if using apache or a server that has a similar mechanism modify .htaccess in your WEBSERVER_ROOTDIR or in the subdir where those settings shall apply as follows

    ErrorDocument 400 /cgi-bin/error500.cgi
    ErrorDocument 401 /cgi-bin/error500.cgi
    ErrorDocument 402 /cgi-bin/error500.cgi
    ErrorDocument 403 /cgi-bin/error500.cgi
    ErrorDocument 404 /cgi-bin/error500.cgi
    ErrorDocument 500 /cgi-bin/error500.cgi
    

    put the script in its place and modify it as needed

    #!/usr/bin/perl -wT use strict; $|++; BEGIN { unshift @INC, '/home/little/lib'; unshift @INC, '/home/little/extlib'; } use CGI qw(-compile :all); $CGI::DISABLE_UPLOADS = 1; $CGI::POST_MAX = 0; my $url = 'http://little.perlmonk.org/'; #print redirect(-uri => "$url", -expires=>"now") if ($ENV{'REDIRECT_RE +DIRECT_STATUS'} eq "200"); use CGI::SSI(autotie => 'STDOUT'); #use CGI::Pretty; use XML::Simple; my $messages = ""; $messages = XMLin('/home/little/my/prefs/sysmesg.xml'); autoEscape(undef); print header(-status=>$ENV{'REDIRECT_STATUS'},-charset=>'iso-8859-1', -expir +es=>"now"), #'<!--#include virtual="/includes/logic/docinfo.shtml" -->', start_html( -title=>$messages->{error}->{$ENV{'REDIRECT_STATUS'}}->{title}, -head=>meta({ -http_equiv=>'Content-Type', -content => 'text/html; + charset=iso-8859-1'}), -base=>'true', -xbase=>$url, -lang=>'de-DE', -style=>{-src=>'/styles/rb_app.css'}, # -script=>[ # {-language=>'JavaScript', # -src=>'/scripts/rb_menu.js'} # ] ), #'<!--#include virtual="/includes/header/header.shtml" -->', div({-id=>"main"}, h1($ENV{'REDIRECT_STATUS'}." - ".$messages->{error}->{$ENV{'REDIRE +CT_STATUS'}}->{title}), p($messages->{error}->{$ENV{'REDIRECT_STATUS'}}->{description}), ), #'<pre><!--#printenv --></pre>', '<!--#include virtual="/includes/footer.shtml" -->', #end_html() ; 1;

    It's possibly not the best one of its kind but suffices at least my needs. *smile*

    and here is the according xml file

    <?xml version="1.0" ?> <messages> <error name="400"> <title><![CDATA[Ung&uuml;ltige Anfrage]]></title> <description><![CDATA[ Das angeforderte Dokument existiert nicht oder nicht m +ehr auf diesem Server oder wurde an eine andere Stelle verschoben. ]]></description> </error> <error name="401"> <title><![CDATA[Autorsierung erforderlich]]></title> <description><![CDATA[ Das angeforderte Dokument ist gegen unerlaubten Zugrif +f gesch&uuml;tzt. F&uuml;r den Zugriff ist ein g&uuml;ltiger Benutzer +name (Login) und ein Passwort erforderlich. ]]></description> </error> <error name="402"> <title><![CDATA[Zugriff kostenpflichtig]]></title> <description><![CDATA[ Wenn Sie diese Seite sehen, d&uuml;rfen Sie uns eine f +reiwillige Spende &uuml;bersenden. :-) ]]></description> </error> <error name="403"> <title><![CDATA[Zugriff verweigert]]></title> <description><![CDATA[ Das angeforderte Dokument ist nicht &ouml;ffentlich zu +g&auml;nglich. ]]></description> </error> <error name="404"> <title><![CDATA[Dokument nicht gefunden]]></title> <description><![CDATA[ Das angeforderte Dokument existiert nicht oder nicht m +ehr auf diesem Server oder wurde an eine andere Stelle verschoben. ]]></description> </error> <error name="420"> <title><![CDATA[Zeitweise nicht verf&uuml;gbar]]></tit +le> <description><![CDATA[ Das angeforderte Dokument existiert auf diesem Server +ist jedoch in Bearbeitung und steht daher zur Zeit leider nicht zur V +erf&uuml;gung. Bitte versuchen Sie es sp&auml;ter erneut. Vielen Dank + f&uuml;r Ihr Verst&auml;ndnis. ]]></description> </error> <error name="500"> <title><![CDATA[Interner Server-Fehler]]></title> <description><![CDATA[ Bei der Bearbeitung der Anfrage hat eine Anwendung ein +en Fehler verursacht. ]]></description> </error> <error name="other"> <title><![CDATA[Fehler]]></title> <description><![CDATA[ Bei der Bearbeitung der Anfrage ist ein Fehler aufgetr +eten. ]]></description> </error> </messages>

    Have a nice day
    All decision is left to your taste

    Update
    Or see CGI::Test::Page::Error for a module.