Skip to content

Commit a928527

Browse files
authored
Merge pull request #122 from codegram/improve-errors-on-nonhal-response
Improve error message when server returns invalid data
2 parents 7fcdcfc + e20f2b0 commit a928527

File tree

5 files changed

+42
-9
lines changed

5 files changed

+42
-9
lines changed

.travis.yml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,16 @@ sudo: false
44

55
matrix:
66
include:
7-
- rvm: 2.3.1
7+
- rvm: 2.4.1
8+
- rvm: 2.4.1
89
script:
910
- bundle exec danger
10-
- rvm: 2.3.1
11-
- rvm: 2.3.0
12-
- rvm: 2.2.5
13-
- rvm: 2.4.0
11+
- rvm: jruby-9.1.12.0
12+
- rvm: jruby-head
13+
- rvm: 2.2.7
14+
- rvm: 2.3.4
1415
- rvm: rbx-2
1516
- rvm: ruby-head
16-
- rvm: jruby-head
17-
- rvm: jruby-9.1.7.0
1817
allow_failures:
1918
- rvm: ruby-head
2019
- rvm: jruby-head

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
### 0.8.6 (Next)
22

3+
* [#122](https://github.com/codegram/hyperclient/pull/122): Improve error message when server returns invalid data - [@ivoanjo](https://github.com/ivoanjo).
34
* Your contribution here.
45

56
### 0.8.5 (July 5, 2017)

features/steps/default_config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class Spinach::Features::DefaultConfig < Spinach::FeatureSteps
1212
end
1313

1414
step 'I send some data to the API' do
15-
stub_request(:post, 'http://api.example.org/posts')
15+
stub_request(:post, 'http://api.example.org/posts').to_return(headers: { 'Content-Type' => 'application/hal+json' })
1616
assert_equal 200, api._links.posts._post(title: 'My first blog post')._response.status
1717
end
1818

lib/hyperclient/resource.rb

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
require 'forwardable'
22

33
module Hyperclient
4+
# Public: Exception that is raised when passing in invalid representation data
5+
# for the resource.
6+
class InvalidRepresentationError < ArgumentError
7+
attr_reader :representation
8+
9+
def initialize(error_description, representation)
10+
super(error_description)
11+
@representation = representation
12+
end
13+
end
14+
415
# Public: Represents a resource from your API. Its responsability is to
516
# ease the way you access its attributes, links and embedded resources.
617
class Resource
@@ -29,8 +40,9 @@ class Resource
2940
# representation - The hash with the HAL representation of the Resource.
3041
# entry_point - The EntryPoint object to inject the configutation.
3142
def initialize(representation, entry_point, response = nil)
32-
representation = representation ? representation.dup : {}
43+
representation = validate(representation)
3344
links = representation['_links'] || {}
45+
3446
@_links = LinkCollection.new(links, links['curies'], entry_point)
3547
@_embedded = ResourceCollection.new(representation['_embedded'], entry_point)
3648
@_attributes = Attributes.new(representation)
@@ -68,6 +80,21 @@ def fetch(key, *args)
6880

6981
private
7082

83+
# Internal: Ensures the received representation is a valid Hash-lookalike.
84+
def validate(representation)
85+
return {} unless representation
86+
87+
if representation.respond_to?(:to_hash)
88+
representation.to_hash.dup
89+
else
90+
raise InvalidRepresentationError.new(
91+
"Invalid representation for resource (got #{representation.class}, expected Hash). " \
92+
"Is your web server returning JSON HAL data with a 'Content-Type: application/hal+json' header?",
93+
representation
94+
)
95+
end
96+
end
97+
7198
# Internal: Returns the self Link of the Resource. Used to handle the HTTP
7299
# methods.
73100
def _self_link

test/hyperclient/resource_test.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ module Hyperclient
4040

4141
resource._response.body.must_equal body
4242
end
43+
44+
describe 'with an invalid representation' do
45+
it 'raises an InvalidRepresentationError' do
46+
proc { Resource.new('invalid representation data', entry_point) }.must_raise InvalidRepresentationError
47+
end
48+
end
4349
end
4450

4551
describe '_links' do

0 commit comments

Comments
 (0)