Subject: | Reducing $SIG{__DIE__} errors in find() |
We updated Opsview to the latest DBIx::Class 0.08124 and got loads of unexpected errors.
In one script, we set $SIG{__DIE__} to catch any unexpected conditions and store those. With
the update, we were getting lots of errors with:
DBIx::Class::InflateColumn::get_inflated_column(): Unable to satisfy requested constraint
'name', no values for column(s): 'name' at (eval 1396) line 2
This is due to _build_unique_cond issuing a throw_exception when conditions are passed in
that do not match with the unique_conditions it expects. However, a call like $rs->find(1)
will try all the different unique constraints to see if it can find something, thus causing the
above message to get thrown in non-exceptional circumstances.
I've made a patch against 0.08124 (attached) which tells _build_unique_cond to avoid
throwing this error if a flag is set. There is also an update to t/60core.t to catch this situation.
Can this go in a future DBIx-Class release?
Subject: | dbix_class_with_less_dies.patch |
diff -ur DBIx-Class-0.08124/lib/DBIx/Class/ResultSet.pm DBIx-Class-0.08124.with_less_dies/lib/DBIx/Class/ResultSet.pm
--- DBIx-Class-0.08124/lib/DBIx/Class/ResultSet.pm 2010-10-27 23:15:17.000000000 +0000
+++ DBIx-Class-0.08124.with_less_dies/lib/DBIx/Class/ResultSet.pm 2010-12-09 11:17:39.000000000 +0000
@@ -552,9 +552,7 @@
join "\x00", sort $rsrc->unique_constraint_columns($c_name)
}++;
- push @unique_queries, try {
- $self->_build_unique_cond ($c_name, $call_cond)
- } || ();
+ push @unique_queries, ( $self->_build_unique_cond ($c_name, $call_cond, 1) || () );
}
$final_cond = @unique_queries
@@ -612,7 +610,7 @@
}
sub _build_unique_cond {
- my ($self, $constraint_name, $extra_cond) = @_;
+ my ($self, $constraint_name, $extra_cond, $hide_throw) = @_;
my @c_cols = $self->result_source->unique_constraint_columns($constraint_name);
@@ -627,6 +625,7 @@
$final_cond = { map { $_ => $final_cond->{$_} } @c_cols };
if (my @missing = grep { ! defined $final_cond->{$_} } (@c_cols) ) {
+ return undef if $hide_throw;
$self->throw_exception( sprintf ( "Unable to satisfy requested constraint '%s', no values for column(s): %s",
$constraint_name,
join (', ', map { "'$_'" } @missing),
diff -ur DBIx-Class-0.08124/t/60core.t DBIx-Class-0.08124.with_less_dies/t/60core.t
--- DBIx-Class-0.08124/t/60core.t 2010-12-09 11:23:55.000000000 +0000
+++ DBIx-Class-0.08124.with_less_dies/t/60core.t 2010-12-09 11:26:14.000000000 +0000
@@ -8,6 +8,12 @@
use DBICTest;
use DBIC::SqlMakerTest;
+my $die_calls = 0;
+$SIG{__DIE__} = sub {
+ #warn("Died: @_");
+ $die_calls++;
+};
+
my $schema = DBICTest->init_schema();
eval { require DateTime::Format::SQLite };
@@ -147,7 +153,9 @@
is($new_obj->in_storage, 0, 'new artist is not in storage');
}
+$die_calls = 0;
my $cd = $schema->resultset("CD")->find(1);
+is( $die_calls, 0, "No exceptions passed to SIG{__DIE__} due to looking for unique keys" );
my %cols = $cd->get_columns;
is(keys %cols, 6, 'get_columns number of columns ok');