perl5-dbi/dbi

DBI::err can be undefined when connection fails with an HandleError

atoomic opened this issue · 4 comments

Steps to reproduce:

  • update to DBI 1.635 or 1.636
  • run this code
#!/usr/bin/env perl

use strict;
use warnings;

use DBI;

use v5.014;

sub handle_error { 
    my ( $str, $dbh, $retval ) = @_;

    warn "one error...";  
    $dbh->{'RaiseError'};# and 'boom';

    return;
}

my $f = q{/tmp/I/do/not/exist!!!};

eval {
    DBI->connect( "dbi:SQLite:dbname=$f", "", "", { HandleError => \&handle_error } ) or die;
    1
} or do {
    say "catch...", $@;
    say 'DBI::str: ', $DBI::err;
}

Before update to 1.636 ( or using df9b142^)

> perl524 test.pl
one error... at test.pl line 13.
DBI connect('dbname=/tmp/I/do/not/exist!!!','',...) failed: unable to open database file at test.pl line 22.
catch...Died at test.pl line 22.

DBI::str: 14

With 1.636 (or simply with df9b142)

> perl524 test.pl
one error... at test.pl line 13.
DBI connect('dbname=/tmp/I/do/not/exist!!!','',...) failed: unable to open database file at test.pl line 22.
catch...Died at test.pl line 22.

Use of uninitialized value $DBI::err in say at test.pl line 26.
DBI::str:

This is a regression introduced by commit df9b142 which is adding an extra copy_statement_to_parent call.

Commenting the 'copy_statement_to_parent' call in set_err_sv fixes it.

The original copy_statement_to_parent was also checking that this was happening during an execute using 'ima_flags & IMA_COPY_UP_STMT' extra check. Wonder if you should also do the same thing there to avoid this problem.

Note that if we do not check $dbh->{'RaiseError'}; in the error handler than it's not triggered.
(commenting the #$dbh->{'RaiseError'};# and 'boom'; line do not expose the bug)

Please retest with master, or the next release (1.637), as I think it was fixed by 9ba7b04 from PR #34.

FYI I'll close this as fixed unless I hear otherwise before long.

Closing, presumed fixed by 9ba7b04 from PR #34.