From: Peter Rabbitson Date: Tue, 9 Aug 2011 04:49:06 +0000 (+0200) Subject: Throw a sensible error when a malformed 'as'-spec is supplied X-Git-Tag: v0.08196~27 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class.git;a=commitdiff_plain;h=ce9f555e55e767a287831c0fcccb337cc36905de Throw a sensible error when a malformed 'as'-spec is supplied --- diff --git a/Changes b/Changes index 3139ec3..275273f 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,7 @@ Revision history for DBIx::Class - Fix tests for DBD::SQLite >= 1.34. - Fix the find() condition heuristics being invoked even when the call defaults to 'primary' (i.e. when invoked with bare values) + - Throw much clearer error on incorrect inflation spec * Misc - No longer depend on Variable::Magic now that a pure-perl diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 4eaa431..60c854b 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -1139,23 +1139,38 @@ sub inflate_result { foreach my $pre (keys %{$prefetch||{}}) { - my $pre_source = $source->related_source($pre) - or $class->throw_exception("Can't prefetch non-existent relationship ${pre}"); - - my $accessor = $source->relationship_info($pre)->{attrs}{accessor} - or $class->throw_exception("No accessor for prefetched $pre"); - - my @pre_vals; + my (@pre_vals, $is_multi); if (ref $prefetch->{$pre}[0] eq 'ARRAY') { + $is_multi = 1; @pre_vals = @{$prefetch->{$pre}}; } - elsif ($accessor eq 'multi') { - $class->throw_exception("Implicit prefetch (via select/columns) not supported with accessor 'multi'"); - } else { @pre_vals = $prefetch->{$pre}; } + my $pre_source = try { + $source->related_source($pre) + } + catch { + $class->throw_exception(sprintf + + "Can't inflate manual prefetch into non-existent relationship '%s' from '%s', " + . "check the inflation specification (columns/as) ending in '%s.%s'.", + + $pre, + $source->source_name, + $pre, + (keys %{$pre_vals[0][0]})[0] || 'something.something...', + ); + }; + + my $accessor = $source->relationship_info($pre)->{attrs}{accessor} + or $class->throw_exception("No accessor type declared for prefetched $pre"); + + if (! $is_multi and $accessor eq 'multi') { + $class->throw_exception("Manual prefetch (via select/columns) not supported with accessor 'multi'"); + } + my @pre_objects; for my $me_pref (@pre_vals) { diff --git a/t/prefetch/incomplete.t b/t/prefetch/incomplete.t index a93e693..8682ba7 100644 --- a/t/prefetch/incomplete.t +++ b/t/prefetch/incomplete.t @@ -6,8 +6,6 @@ use Test::Exception; use lib qw(t/lib); use DBICTest; -plan tests => 9; - my $schema = DBICTest->init_schema(); lives_ok(sub { @@ -51,3 +49,14 @@ lives_ok(sub { is ($cd->artist->name, 'Random Boy Band', 'Artist object has correct name'); }, 'implicit keyless prefetch works'); + +# sane error +throws_ok( + sub { + $schema->resultset('Track')->search({}, { join => { cd => 'artist' }, '+columns' => 'artist.name' } )->next; + }, + qr|\QCan't inflate manual prefetch into non-existent relationship 'artist' from 'Track', check the inflation specification (columns/as) ending in 'artist.name'|, + 'Sensible error message on mis-specified "as"', +); + +done_testing;