Skip to content

Commit

Permalink
Throw better error when polymorphic type not found
Browse files Browse the repository at this point in the history
If you are sideposting a polymorphic relationship, and pass a jsonapi
type that is not registered, we would throw a confusing error. Now we
throw an explicit error with information about what's happening.
  • Loading branch information
Lee Richmond committed Apr 4, 2019
1 parent 10f2188 commit 0b7c716
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

### master (unreleased)

Misc:

- [#123](https://github.com/graphiti-api/graphiti/pull/123) Throw
better error when polymorphic type not found.

<!-- ### [version (YYYY-MM-DD)](diff_link) -->
<!-- Breaking changes:-->
<!-- Features:-->
Expand Down
22 changes: 22 additions & 0 deletions lib/graphiti/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,28 @@ def message
end
end

class PolymorphicSideloadTypeNotFound < Base
def initialize(sideload, name)
@sideload = sideload
@name = name
end

def message
<<~MSG
#{@sideload.parent_resource}: Tried to find a Resource with type '#{@name.inspect}', but did not find one!
This is because either a Resource with that type doesn't exist, or it's not registered on the sideload. The below example shows how to register a Resource with this sideload. Make sure one of the registered Resources has type '#{@name.inspect}'
polymorphic_belongs_to #{@sideload.name.inspect} do
group_by(#{@sideload.grouper.field_name.inspect}) do
on(:foo)
on(:foo).belongs_to :foo, resource: FooResource (long-hand example)
end
end
MSG
end
end

class PolymorphicSideloadChildNotFound < Base
def initialize(sideload, name)
@sideload = sideload
Expand Down
9 changes: 9 additions & 0 deletions lib/graphiti/sideload/polymorphic_belongs_to.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ def child_for_type(type)
end
end

def child_for_type!(type)
if child = child_for_type(type)
child
else
err = ::Graphiti::Errors::PolymorphicSideloadTypeNotFound
raise err.new(self, type)
end
end

def resolve(parents, query, graph_parent)
parents.group_by(&grouper.field_name).each_pair do |group_name, group|
next if group_name.nil? || grouper.ignore?(group_name)
Expand Down
2 changes: 1 addition & 1 deletion lib/graphiti/util/relationship_payload.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def payload_for(sideload, relationship_payload)

# For polymorphic *sideloads*, grab the correct child sideload
if sideload.resource.type != type && sideload.type == :polymorphic_belongs_to
sideload = sideload.child_for_type(type)
sideload = sideload.child_for_type!(type)
end

# For polymorphic *resources*, grab the correct child resource
Expand Down
2 changes: 1 addition & 1 deletion spec/filtering_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ def self.name
params[:filter] = {enum_age: {eq: 2}}
expect {
records
}.to raise_error(Graphiti::Errors::InvalidFilterValue, /Allowlist: \[1, 3, 5]/)
}.to raise_error(Graphiti::Errors::InvalidFilterValue, /Allowlist: \[1, 3, 5\]/)
end
end

Expand Down
15 changes: 13 additions & 2 deletions spec/persistence_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2439,14 +2439,15 @@ def self.name
end

describe "polymorphic_belongs_to" do
let(:jsonapi_type) { 'visas' }
let(:payload) do
{
data: {
type: "employees",
relationships: {
credit_card: {
data: {
type: "visas",
type: jsonapi_type,
'temp-id': "abc123",
method: "create",
},
Expand All @@ -2456,7 +2457,7 @@ def self.name
included: [
{
'temp-id': "abc123",
type: "visas",
type: jsonapi_type,
attributes: {number: 123456},
},
],
Expand Down Expand Up @@ -2505,6 +2506,16 @@ def self.name
expect(data.credit_card.number).to eq(123456)
expect(data.credit_card_type).to eq(:Visa)
end

context 'when unknown jsonapi type' do
let(:jsonapi_type) { 'foos' }

it 'raises helpful error' do
expect {
klass.build(payload).save
}.to raise_error(Graphiti::Errors::PolymorphicSideloadTypeNotFound)
end
end
end

context "when multiple levels" do
Expand Down

0 comments on commit 0b7c716

Please # to comment.