diff --git a/lib/geocoder/exceptions.rb b/lib/geocoder/exceptions.rb index 7445c662dc7aa548cc065c69452fa8f3573e0bd9..01153aaf5303a81b2e9aaa5b90e65fdf85e348d9 100644 --- a/lib/geocoder/exceptions.rb +++ b/lib/geocoder/exceptions.rb @@ -9,6 +9,14 @@ module Geocoder class OverQueryLimitError < Error end + class ResponseParseError < Error + attr_reader :response + + def initialize(response) + @response = response + end + end + class RequestDenied < Error end diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb index 9f79d8a0ed2439f8aea43af753715f61c7cec22f..43f7cc55f02ff34eb5f7adc571150c225134118e 100644 --- a/lib/geocoder/lookups/base.rb +++ b/lib/geocoder/lookups/base.rb @@ -182,6 +182,8 @@ module Geocoder else JSON.parse(data) end + rescue => err + raise_error(ResponseParseError.new(data)) or warn "Geocoding API's response was not valid JSON." end ## @@ -189,8 +191,6 @@ module Geocoder # def parse_raw_data(raw_data) parse_json(raw_data) - rescue - warn "Geocoding API's response was not valid JSON." end ## diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb index ef1e41c75cdab9f1498263f405de10cb6696a951..9b2d98be8ff2e77333004234da7ead42e02c0b44 100644 --- a/lib/geocoder/lookups/google.rb +++ b/lib/geocoder/lookups/google.rb @@ -19,7 +19,8 @@ module Geocoder::Lookup private # --------------------------------------------------------------- def valid_response?(response) - status = parse_json(response.body)["status"] + json = parse_json(response.body) + status = json["status"] if json super(response) and ['OK', 'ZERO_RESULTS'].include?(status) end diff --git a/lib/geocoder/lookups/okf.rb b/lib/geocoder/lookups/okf.rb index ae45e06a4680c8e61aaf05eeae547495aff5e03a..54909bb2dcd8a330710676155193f1a905ab4f15 100644 --- a/lib/geocoder/lookups/okf.rb +++ b/lib/geocoder/lookups/okf.rb @@ -15,7 +15,8 @@ module Geocoder::Lookup private # --------------------------------------------------------------- def valid_response?(response) - status = parse_json(response.body)["status"] + json = parse_json(response.body) + status = json["status"] if json super(response) and ['OK', 'ZERO_RESULTS'].include?(status) end diff --git a/test/test_helper.rb b/test/test_helper.rb index 2c197f07040b1a0f2e755cd260a129e3bac6e50d..c2140fdf45896b55a86a314eb53b40998fc54629 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -107,6 +107,10 @@ module Geocoder raise TimeoutError if query.text == "timeout" raise SocketError if query.text == "socket_error" raise Errno::ECONNREFUSED if query.text == "connection_refused" + if query.text == "invalid_json" + return MockHttpResponse.new(:body => 'invalid json', :code => 200) + end + read_fixture fixture_for_query(query) end end @@ -409,4 +413,8 @@ class MockHttpResponse @code = options[:code].to_s @body = options[:body] end + + def [](key) + send key if respond_to?(key) + end end diff --git a/test/unit/error_handling_test.rb b/test/unit/error_handling_test.rb index 493d0ba0e937c21f9526bb14849df04a624123f1..dedbe5061248e9c337a853641266b98c0deca884 100644 --- a/test/unit/error_handling_test.rb +++ b/test/unit/error_handling_test.rb @@ -18,6 +18,29 @@ class ErrorHandlingTest < GeocoderTestCase end end + def test_always_raise_response_parse_error + Geocoder.configure(:always_raise => [Geocoder::ResponseParseError]) + [:freegeoip, :google, :okf].each do |l| + lookup = Geocoder::Lookup.get(l) + set_api_key!(l) + assert_raises Geocoder::ResponseParseError do + lookup.send(:results, Geocoder::Query.new("invalid_json")) + end + end + end + + def test_never_raise_response_parse_error + [:freegeoip, :google, :okf].each do |l| + lookup = Geocoder::Lookup.get(l) + set_api_key!(l) + silence_warnings do + assert_nothing_raised do + lookup.send(:results, Geocoder::Query.new("invalid_json")) + end + end + end + end + def test_always_raise_timeout_error Geocoder.configure(:always_raise => [TimeoutError]) Geocoder::Lookup.all_services_except_test.each do |l|