Subject: | Nested 'catch' subs not being run |
Date: | Sun, 27 Mar 2011 15:41:29 +1300 |
To: | David Wheeler via RT <bug-DBIx-Connector [...] rt.cpan.org> |
From: | Mark Lawrence <nomad [...] null.net> |
In #65195 I mentioned I had an issue with different behaviour between
fixup and the (no_)ping modes. It went away for a while and now came
back (due to changes in my code) but at least this time I managed to
drag up a test case:
use strict;
use warnings;
use DBIx::Connector;
my $conn = DBIx::Connector->new(
'dbi:SQLite:dsn=junk', '', '', { RaiseError => 1}
);
sub inner {
my $conn = shift;
$conn->run(sub {
die 'WTF!';
}, catch => sub {
die 'inner said: '. $_;
});
}
sub outer {
my $conn = shift;
$conn->run(sub {
inner( $conn );
}, catch => sub {
die 'outer said: '. $_;
});
}
foreach my $mode (qw/ping no_ping fixup/) {
$conn->mode( $mode );
eval { outer($conn); };
warn $mode.': '. $@;
}
If you run this you get (I added indentation):
ping: outer said: inner said: WTF! at k line 14.
no_ping: outer said: inner said: WTF! at k line 14.
fixup: outer said: WTF! at k line 14.
Even worse, if you change 'run' to 'txn' you get this:
ping: outer said: WTF! at k line 14.
no_ping: outer said: WTF! at k line 14.
fixup: outer said: WTF! at k line 14.
which doesn't seem right at all.
I hope this is clear. I think there are two issues:
1. 'run' does not catch nested 'catch' blocks in 'fixup' mode.
2. 'txn' is not catching *any* nested 'catch' blocks.
In my mind the DBIx::Connector exception handling should work the same
way as the eval function, and I think that was your intention:
sub inner {
eval { die 'WTF'};
die 'inner said: '.$@;
}
sub outer {
eval { inner};
die 'outer said: '. $@;
}
outer; # outer said: inner said: WTF
What do you think?
--
Mark Lawrence