On Fri, 3 Dec 2004 21:04:11 +0000, Tim Bunce <[EMAIL PROTECTED]> wrote:
> On Thu, Dec 02, 2004 at 04:07:13PM -0800, Jonathan Leffler wrote:
> > I was just getting ready to ship DBD::Informix 2004.02 when I made the
> > mistake of testing it with Perl 5.6.1 and DBI 1.46.
> > I ran into problems with a DBD::Informix test that was expecting an error
> > code to be set in a $SIG{__WARN__} handler.
> 
> > my $msg;
> > $SIG{__WARN__} = sub { $msg = $_[0]; };
> > $dbh = DBI->connect("dbi:Informix:$dbname", $user, $pass, { AutoCommit => 
> > 0, PrintError => 1 });
> > print "not ok 8\n" unless($msg && $msg =~ /-256:/);
> >
> > The comparison in the last-but-one line is failing - instead of the -256
> > message number plus colon, the code is seeing '(no error string)', even
> > though when I subsequently print $DBI::errstr, the correct message is
> > visible.
> 
> Odd. I thought that bug was fixed in DBI 1.43. See top line of:
> 
>   
> http://search.cpan.org/~timb/DBI/Changes#Changes_in_DBI_1.43_(svn_rev_377),_2nd_July_2004
> 
> It's related to the timing of when perl calls DESTROY (which changes
> sometimes between releases) and the way that dbh errors values then
> get copied up the the drh.
> 
> Here's the relevant part of the DBI->connect method:
> 
>         unless ($dbh = $drh->$connect_meth($dsn, $user, $pass, $attr)) {
>             $user = '' if !defined $user;
>             $dsn = '' if !defined $dsn;
>             # $drh->errstr isn't safe here because $dbh->DESTROY may not have
>             # been called yet and so the dbh errstr would not have been copied
>             # up to the drh errstr. Certainly true for connect_cached!
>             my $errstr = $DBI::errstr;
>             $errstr = '(no error string)' if !defined $errstr;
>             my $msg = "$class connect('$dsn','$user',...) failed: $errstr";
>             DBI->trace_msg("       $msg\n");
>             # XXX HandleWarn
>             unless ($attr->{HandleError} && $attr->{HandleError}->($msg, 
> $drh, $dbh)) {
>                 Carp::croak($msg) if $attr->{RaiseError};
>                 Carp::carp ($msg) if $attr->{PrintError};
>             }
>             $! = 0; # for the daft people who do DBI->connect(...) || die 
> "$!";
>             return $dbh; # normally undef, but HandleError could change it
>         }
> 
> The code used to use $drh->errstr but, as the comment says, that's not safe.

I guess the question then becomes - how does $DBI::errstr get set?  It
isn't visible in the code here, so it must be in the infrastructure
that ends up in $drh->$connect_meth().  Unless the drivers are
supposed to set it directly themselves?

> Assuming you really are using 1.46 (please triple check)

Yes - afraid so.  All versions from 1.43 upwards have the problem (for
me, on my machine).

> then you'll need to do some digging around that code to find out what's going 
> on.

OK - thanks for the information.  I'll do a bit of poking, but I'm not
sure whether it'll be to any useful effect.

[...message typed Friday pm - I wondered where it got to!...]


-- 
Jonathan Leffler <[EMAIL PROTECTED]>  #include <disclaimer.h>
Guardian of DBD::Informix - v2003.04 - http://dbi.perl.org
"I don't suffer from insanity - I enjoy every minute of it."

Reply via email to