From 40ac60c43b6070222b5402b4100a4de60dab44f5 Mon Sep 17 00:00:00 2001
From: Robert Wachs <github@robert-wachs.de>
Date: Sun, 14 Dec 2014 00:45:37 +0100
Subject: [PATCH] Adds possibility to raise error when response parsing fails

---
 lib/geocoder/exceptions.rb       |  8 ++++++++
 lib/geocoder/lookups/base.rb     |  4 ++--
 test/test_helper.rb              |  8 ++++++++
 test/unit/error_handling_test.rb | 23 +++++++++++++++++++++++
 4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/lib/geocoder/exceptions.rb b/lib/geocoder/exceptions.rb
index 7445c662..01153aaf 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 9f79d8a0..43f7cc55 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/test/test_helper.rb b/test/test_helper.rb
index bcd31d21..89c09722 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -111,6 +111,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
@@ -413,4 +417,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 493d0ba0..dedbe506 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|
-- 
GitLab