Skip to content

Commit

Permalink
Attach URI to Read Error
Browse files Browse the repository at this point in the history
When getting a `404` or `500` error it was impossible to know which
file was causing the problem with a schema that had many external
references.  This attaches the uri that failed to the error if it's
an OpenURI error, which makes is easy to know what refrenced file
was the culprit.
  • Loading branch information
benfalk authored and iainbeeston committed Sep 29, 2016
1 parent a485620 commit 3f07ef0
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Made all `validate*` methods on `JSON::Validator` ultimately call `validate!`
- Updated addressable dependency to 2.4.0
- Attached failed `uri` or `pathname` to read errors for more meaning

## [2.6.2] - 2016-05-13

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Expand Up @@ -32,3 +32,4 @@ CONTRIBUTORS
* Ben Kirzhner - @benkirzhner
* RST-J - @RST-J
* Christian Treppo - @treppo
* Benjamin Falk - @benfalk
36 changes: 32 additions & 4 deletions lib/json-schema/schema/reader.rb
Expand Up @@ -3,9 +3,8 @@

module JSON
class Schema
# Raised by {JSON::Schema::Reader} when one of its settings indicate
# a schema should not be readed.
class ReadRefused < StandardError
# Base for any reading exceptions encountered by {JSON::Schema::Reader}
class ReadError < StandardError
# @return [String] the requested schema location which was refused
attr_reader :location

Expand All @@ -15,7 +14,30 @@ class ReadRefused < StandardError
def initialize(location, type)
@location = location
@type = type
super("Read of #{type == :uri ? 'URI' : type} at #{location} refused!")
super(error_message)
end

private

def type_string
type == :uri ? 'URI' : type.to_s
end
end

# Raised by {JSON::Schema::Reader} when one of its settings indicate
# a schema should not be read.
class ReadRefused < ReadError
private
def error_message
"Read of #{type_string} at #{location} refused"
end
end

# Raised by {JSON::Schema::Reader} when an attempt to read a schema fails
class ReadFailed < ReadError
private
def error_message
"Read of #{type_string} at #{location} failed"
end
end

Expand Down Expand Up @@ -58,6 +80,8 @@ def initialize(options = {})
# @raise [JSON::Schema::ReadRefused] if +accept_uri+ or +accept_file+
# indicated the schema could not be read
# @raise [JSON::Schema::ParseError] if the schema was not a valid JSON object
# @raise [JSON::Schema::ReadFailed] if reading the location was acceptable but the
# attempt to retrieve it failed
def read(location)
uri = JSON::Util::URI.parse(location.to_s)
body = if uri.scheme.nil? || uri.scheme == 'file'
Expand Down Expand Up @@ -98,6 +122,8 @@ def read_uri(uri)
else
raise JSON::Schema::ReadRefused.new(uri.to_s, :uri)
end
rescue OpenURI::HTTPError, SocketError
raise JSON::Schema::ReadFailed.new(uri.to_s, :uri)
end

def read_file(pathname)
Expand All @@ -106,6 +132,8 @@ def read_file(pathname)
else
raise JSON::Schema::ReadRefused.new(pathname.to_s, :file)
end
rescue Errno::ENOENT
raise JSON::Schema::ReadFailed.new(pathname.to_s, :file)
end
end
end
Expand Down
14 changes: 12 additions & 2 deletions test/bad_schema_ref_test.rb
Expand Up @@ -19,9 +19,15 @@ def test_bad_uri_ref
}

data = [1,2,3]
assert_raises(Errno::ENOENT) do
error = assert_raises(JSON::Schema::ReadFailed) do
JSON::Validator.validate(schema,data)
end

expanded_path = File.expand_path("../../google.json", __FILE__)

assert_equal(:file, error.type)
assert_equal(expanded_path, error.location)
assert_equal("Read of file at #{expanded_path} failed", error.message)
end

def test_bad_host_ref
Expand All @@ -32,8 +38,12 @@ def test_bad_host_ref
}

data = [1,2,3]
assert_raises(SocketError, OpenURI::HTTPError) do
error = assert_raises(JSON::Schema::ReadFailed) do
JSON::Validator.validate(schema,data)
end

assert_equal(:uri, error.type)
assert_equal("http://ppcheesecheseunicornnuuuurrrrr.example.invalid/json.schema", error.location)
assert_equal("Read of URI at http://ppcheesecheseunicornnuuuurrrrr.example.invalid/json.schema failed", error.message)
end
end
6 changes: 5 additions & 1 deletion test/schema_reader_test.rb
Expand Up @@ -57,9 +57,13 @@ def test_accept_file_proc

def test_file_scheme
reader = JSON::Schema::Reader.new(:accept_uri => true, :accept_file => false)
assert_raises(JSON::Schema::ReadRefused) do
error = assert_raises(JSON::Schema::ReadRefused) do
reader.read('file://' + ADDRESS_SCHEMA_PATH)
end

assert_equal(:file, error.type)
assert_equal(ADDRESS_SCHEMA_PATH, error.location)
assert_equal("Read of file at #{ADDRESS_SCHEMA_PATH} refused", error.message)
end

def test_parse_error
Expand Down

0 comments on commit 3f07ef0

Please sign in to comment.