Subject: | DBI AutoCommit perldebug eval $@ problem |
Date: | Thu, 12 Jun 2008 12:06:25 -0600 |
To: | "'bug-DBI [...] rt.cpan.org'" <bug-DBI [...] rt.cpan.org> |
From: | "Roberts, Evan" <EvanRoberts [...] mt.gov> |
I've run into a problem with DBI where if it throws a DIE $@ will not be set after the eval. This is bad. I've seen the problem with DBD::Oracle and DBD::mysql. Your code must meet 3 conditions to see this bug:
1) You must be running in the perl debugger.
2) You must have AutoCommit set to 0.
3) You must have your $dbh declared within the eval block (probably has something to do with rolling back when leaving the eval block).
I am running SUSE. Listing of other system information follows:
Show quoted text
> perl -d -e 0
Loading DB routines from perl5db.pl version 1.28
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(-e:1): 0
DB<1> use DBI;
DB<2> p `uname -a`
Linux myhostname 2.6.16.54-0.2.3-bigsmp #1 SMP Thu Nov 22 18:32:07 UTC 2007 i686 i686 i386 GNU/Linux
DB<3> p $]
5.008008
DB<4> p $DBI::VERSION
1.601
DB<5>
I've included a sample script that demonstrates the behavior:
use strict;
use DBI;
#Main code in this block.
eval
{
my $creds;
#$dbh has to be locally scoped in the eval block, assuming it has something to do with rolling back the statement.
my $dbh;
$creds = {'host' => 'host' ,
'user' => 'user' ,
'password' => 'password'};
#Connect to Oracle.
$dbh = DBI->connect("dbi:Oracle:$creds->{host}", $creds->{user}, $creds->{password},{RaiseError =>1});
$dbh->{'AutoCommit'} = 0; #if this line is not here the problem does not happen.
#invalid alter session statement to cause an error.
$dbh->do("ALTE SESSION SET NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'");
}; #end of script.
#if there was an error in the eval $@ should be set.
if($@)
{
#never gets here in *DEBUG MODE ONLY*:(
print "Got the error!";
#throw the error results back out to the console as well.
die $@;
}