From 8e9a4252342881988b693c82bd25f8f0ef7780d1 Mon Sep 17 00:00:00 2001
From: Ahmed Adam <aa9409@gmail.com>
Date: Mon, 9 May 2011 22:17:16 +0100
Subject: [PATCH] Add option to not rescue from certain exceptions.

Allows custom handling of geocoding service connection problems.
---
 lib/geocoder/configuration.rb |  7 ++++++-
 lib/geocoder/lookups/base.rb  | 16 ++++++++++++----
 test/geocoder_test.rb         | 13 +++++++++++++
 test/test_helper.rb           |  6 ++++++
 4 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/lib/geocoder/configuration.rb b/lib/geocoder/configuration.rb
index bc5e2b98..3381fb18 100644
--- a/lib/geocoder/configuration.rb
+++ b/lib/geocoder/configuration.rb
@@ -28,7 +28,12 @@ module Geocoder
         [:cache, nil],
 
         # prefix (string) to use for all cache keys
-        [:cache_prefix, "geocoder:"]
+        [:cache_prefix, "geocoder:"],
+
+        # exceptions that should not be rescued by default
+        # (if you want to implement custom error handling);
+        # supports SocketError and TimeoutError
+        [:always_raise, []]
       ]
     end
 
diff --git a/lib/geocoder/lookups/base.rb b/lib/geocoder/lookups/base.rb
index 9d58c7e9..39490e81 100644
--- a/lib/geocoder/lookups/base.rb
+++ b/lib/geocoder/lookups/base.rb
@@ -90,16 +90,24 @@ module Geocoder
         eval("Geocoder::Result::#{self.class.to_s.split(":").last}")
       end
 
+      ##
+      # Raise exception instead of warning for specified exceptions.
+      #
+      def raise_error(err)
+        raise err if Geocoder::Configuration.always_raise.include?(err.class)
+      end
+
+
       ##
       # Returns a parsed search result (Ruby hash).
       #
       def fetch_data(query, reverse = false)
         begin
           parse_raw_data fetch_raw_data(query, reverse)
-        rescue SocketError
-          warn "Geocoding API connection cannot be established."
-        rescue TimeoutError
-          warn "Geocoding API not responding fast enough " +
+        rescue SocketError => err
+          raise_error(err) or warn "Geocoding API connection cannot be established."
+        rescue TimeoutError => err
+          raise_error(err) or warn "Geocoding API not responding fast enough " +
             "(see Geocoder::Configuration.timeout to set limit)."
         end
       end
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index dacfd8e3..82961647 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -357,6 +357,19 @@ class GeocoderTest < Test::Unit::TestCase
   end
 
 
+  def test_always_raise_timeout_error
+    Geocoder::Configuration.always_raise = [TimeoutError]
+    assert_raise(TimeoutError) { Geocoder.search("timeout") }
+    Geocoder::Configuration.always_raise = []
+  end
+
+
+  def test_always_raise_socket_error
+    Geocoder::Configuration.always_raise = [SocketError]
+    assert_raise(SocketError) { Geocoder.search("socket_error") }
+    Geocoder::Configuration.always_raise = []
+  end
+
   # --- Google ---
 
   def test_google_result_components
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 7364498a..f491504a 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -62,6 +62,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         file = case query
           when "no results";   :no_results
           when "no locality";  :no_locality
@@ -76,6 +77,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         file = case query
           when "no results";  :no_results
           else                :madison_square_garden
@@ -88,6 +90,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         file = case query
           when "no results";  :no_results
           when "invalid key"; :invalid_key
@@ -101,6 +104,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         if reverse
           read_fixture "geocoder_ca_reverse.json"
         else
@@ -117,6 +121,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         read_fixture "freegeoip_74_200_247_59.json"
       end
     end
@@ -125,6 +130,7 @@ module Geocoder
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
         raise TimeoutError if query == "timeout"
+        raise SocketError if query == "socket_error"
         if reverse
           read_fixture "bing_reverse.json"
         else
-- 
GitLab