Why It's Better to Refrain from Using CGI::Carp

davebaker58 edited this page Jan 23, 2013 · 1 revision

Sometimes I forget that I don’t need to put

  use CGI::Carp qw( fatalsToBrowser );

into my script in order to get my browser to display compile-time or run-time errors.

CGI::Application by default sends the header that Apache needs to display a compile-time error on my browser, so the browser will show something like this:

   Software error:

   Can't find string terminator '"' anywhere before EOF at Event.pm line 485.
   Compilation failed in require at /www/cgi-bin/event/index.cgi line 31.
   BEGIN failed--compilation aborted at /www/cgi-bin/event/index.cgi line 31.

   For help, please send mail to the webmaster (webmaster@mysite.com), giving this error message and the time and date of the error.

But by default CGI::Application doesn’t seem to send Apache the header it needs to display a run-time error (such as encountering a die statement). Instead the browser displays "500 Server Error."

At one time I thought "use CGI::Carp qw( fatalsToBrowser )" was the way to get run-time errors onto my browser, but the better way is to use 'error_mode' feature included in CGI::Application since version 3.30. You specify the name of one of your runmodes, which causes CGI::Application to handle runtime errors that arise. It also sends the value of Perl’s $@ variable as a parameter to that runmode, and then displays the return value of the runmode.

For example, here are some lines from an application module I wrote called Event.pm:

 package Event;

 . . .

 sub setup {
    . . .
    $self->error_mode( 'my_error_mode' );
    . . .
 }

 sub my_error_mode {
    my ( $self, $err ) = @_;
    my $display = "Error encountered: '$err'; stopped";
    return $display;
 }

 sub process_form {
    . . .
    die "Does not look like an email address"  # This is line 47 of the file
      unless ( $q->param('email') =~ /@/ );
    . . .
 }

When a script uses the above Event.pm module and a user enters "foo" as his email address on a form that invokes the script, this message is displayed:

   Error encountered: 'Does not look like an email address'; stopped at /www/cgi-bin/lib/Event.pm line 47.

What you definitely want to avoid is to use CGI::Carp and the error_mode technique in your script at the same time. As noted above, CGI::Carp isn’t needed with respect to compile- time errors under CGI::Application. If you have put it into your script through habit or for some other reason, the error_mode no longer reports the line of the application module on which a run-time error occurs. Instead you get the number of a line within another module, which is useless for debugging the application module. Here is what the code above would produce if Event.pm has a "use CGI::Carp qw( fatalsToBrowser )" statement in it:

   Error encountered: 'Does not look like an email address'; stopped at /usr/local/lib/perl5/5.8.6/CGI/Carp.pm line 314.