You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Chuck Goehring <cg...@rcisd.com> on 2000/09/09 03:45:46 UTC

Eval block error trapping bug????

Hi,

Having a big problem here.

When I use an eval{} block to trap dbi errors, it doesn't seam to work as
documented under mod_perl.
When I found this problem, I created a test program that connects, prepares
and executes a bogus sql
statement.  The $lsth->execute() || die $DBI::errstr; is triggering the
default "Software Error" message
and the cgi ends.  Toggling RaiseError changes the wording of the error
message but does not affect the
error trapping.  Under mod_perl, the die() within the eval block causes the
program to really die
even with RaiseError => 1.  I thought I had this all nailed down but now I
get un-gracefull error
handling in my web app.  The command line version works correctly.  Both
test programs and the
version info are listed below.

Deploying two major systems & need some help.  Any suggestions?

Thanks
Chuck Goehring
=================================

Versions are as follows:
Windows NT SP5
perl 5.6.0
Apache 1.3.12
ApacheDBI-0.87
mod_perl 1.24
DBD-Oracle-1.03
Dbi-1.13
Jserv 1.1.1
The manual fix for Carp in sub ineval was put in.
The manual fix for Carp::Heavy regarding 'DB'/'DB_tmp' was put in.

====================== startup.pl

use strict;
use Apache ();
use Apache::Registry;
use Apache::DBI();
use CGI qw(-compile :cgi);
use Carp();

1;
__END__

======================= mod_perl test program
use strict;
my $cgiOBJ;
use CGI qw/:standard :html3/;
use CGI::Carp qw(fatalsToBrowser);
use Apache::DBI();
$cgiOBJ = new CGI;

print $cgiOBJ->header(-expires=>'-1d'),
      $cgiOBJ->start_html(-TITLE=>'Testing error handling',
                          -BGCOLOR=>'#FFFFFF');
test3('select dork, pork, cork from rourk'); # A BOGUS sql statement.

print $cgiOBJ->end_html;

sub test3 {  # eval execute
  my ($aSQLStatement) = @_;
  print "test3: eval execute<br>Using SQL: $aSQLStatement";
  my ($dbh, $DefaultDSN, $user, $pa, $lsth);
  $DefaultDSN = 'DBI:Oracle:rciora';
  $user = 'dis';
  $pa = 'dis';

  $dbh = DBI->connect($DefaultDSN, $user, $pa, { RaiseError => 1, PrintError
=> 0, AutoCommit => 0 });   # Returns undef on failure (pg 86).
  eval {
    $lsth = $dbh->prepare($aSQLStatement) or die "Prepare failed:
$DBI::errstr";
    if (!(defined($lsth))) {         # Prepare is supposed to return undef
on failure (pg 108).
      print 'lsth not defined at 1';  # This seams to never print for
Oracle.
    }
    $lsth->execute() || die $DBI::errstr; # die should trigger jump to 'if'
below.
  };
  if ($@) {   # $@ is null after an eval per camel page 161
    print 'Message reported by @ = ' . $@;
  }
  if (!(defined($lsth))) {         # Prepare is supposed to return undef on
failure (pg 108).
    print 'sth not defined at 2';  # This seams to never print for Oracle.
  }
  $dbh->disconnect();
  return;
}

======================= command line perl test program

use strict;
use DBI();

test3('select dork, pork, cork from rourk'); # A BOGUS sql statement.


sub test3 {  # eval execute
  my ($aSQLStatement) = @_;
  my ($dbh, $DefaultDSN, $user, $pa, $lsth);
  $DefaultDSN = 'DBI:Oracle:rciora';
  $user = 'dis';
  $pa = 'dis';

  $dbh = DBI->connect($DefaultDSN, $user, $pa, { RaiseError => 1, PrintError
=> 0, AutoCommit => 0 });   # Returns undef on failure (pg 86).
  eval {
    $lsth = $dbh->prepare($aSQLStatement) or die "Prepare failed:
$DBI::errstr";
    if (!(defined($lsth))) {         # Prepare is supposed to return undef
on failure (pg 108).
      print "\nlsth not defined at 1";  # This seams to never print for
Oracle.
    }
    $lsth->execute() || die $DBI::errstr; # die should trigger jump to 'if'
below.
  };
  if ($@) {   # $@ is null after an eval per camel page 161
    print "\nMessage reported by @ = $@";
  }
  if (!(defined($lsth))) {         # Prepare is supposed to return undef on
failure (pg 108).
    print "\nsth not defined at 2";  # This seams to never print for Oracle.
  }
  $dbh->disconnect();
  return;
}



Re: Eval block error trapping bug????

Posted by Matt Sergeant <ma...@sergeant.org>.
On Sat, 9 Sep 2000, Eric L. Brine wrote:

> > Under mod_perl, the die() within the eval block causes the
> > program to really die.
> 
> Does your program (maybe CGI.pm or something used by CGI.pm?) set
> $SIG{'DIE'}? IIRC, $SIG{'DIE'} has precedence over eval{}, something
> many consider to be a bug.

That's '__DIE__'. This, as usual, is all covered by the guide :)

-- 
<Matt/>

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org | AxKit: http://axkit.org


Re: Eval block error trapping bug????

Posted by "Eric L. Brine" <eb...@home.com>.
> Under mod_perl, the die() within the eval block causes the
> program to really die.

Does your program (maybe CGI.pm or something used by CGI.pm?) set
$SIG{'DIE'}? IIRC, $SIG{'DIE'} has precedence over eval{}, something
many consider to be a bug.

If so, I'd try:
  eval {
    local $SIG{'DIE'}; # undefine $SIG{'DIE'} in this block
    ...normal code...
  };
  if ($@) { ...normal code... }

ELB

Re: Eval block error trapping bug????

Posted by Matt Sergeant <ma...@sergeant.org>.
On Fri, 8 Sep 2000, Chuck Goehring wrote:

> Hi,
> 
> Having a big problem here.
> 
> When I use an eval{} block to trap dbi errors, it doesn't seam to work as
> documented under mod_perl.
> When I found this problem, I created a test program that connects, prepares
> and executes a bogus sql
> statement.  The $lsth->execute() || die $DBI::errstr; is triggering the
> default "Software Error" message
> and the cgi ends.  Toggling RaiseError changes the wording of the error
> message but does not affect the
> error trapping.  Under mod_perl, the die() within the eval block causes the
> program to really die
> even with RaiseError => 1.  I thought I had this all nailed down but now I
> get un-gracefull error
> handling in my web app.  The command line version works correctly.  Both
> test programs and the
> version info are listed below.
> 
> Deploying two major systems & need some help.  Any suggestions?

CGI::Carp is _not_ for people who want to be able to do exception handling
- it implements its very own system wide (and IMHO broken) exception
handler, which prevents eval {} from working properly.

Get rid of it.

(if you understand all the details, add in a "local $SIG{__DIE__};" to the
eval block, but thats not a scaleable solution).

-- 
<Matt/>

Fastnet Software Ltd. High Performance Web Specialists
Providing mod_perl, XML, Sybase and Oracle solutions
Email for training and consultancy availability.
http://sergeant.org | AxKit: http://axkit.org