From eaf68c70a2edacac89d56894a3063a3b4aaf7c49 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Fri, 11 Mar 2011 12:32:24 -0500
Subject: [PATCH] Handle geocoding service timeout gracefully.

This was causing an exception (thanks to github.com/mikepinde).
---
 lib/geocoder/lookups/freegeoip.rb |  4 +---
 lib/geocoder/lookups/google.rb    |  2 +-
 lib/geocoder/lookups/yahoo.rb     |  2 +-
 test/geocoder_test.rb             | 12 ++++++++++++
 test/test_helper.rb               |  3 +++
 5 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/lib/geocoder/lookups/freegeoip.rb b/lib/geocoder/lookups/freegeoip.rb
index dcc5e44f..4ae499af 100644
--- a/lib/geocoder/lookups/freegeoip.rb
+++ b/lib/geocoder/lookups/freegeoip.rb
@@ -10,9 +10,7 @@ module Geocoder::Lookup
       # don't look up a loopback address, just return the stored result
       return reserved_result(query) if loopback_address?(query)
       begin
-        if doc = fetch_data(query, reverse)
-          doc
-        end
+        fetch_data(query, reverse)
       rescue StandardError # Freegeoip.net returns HTML on bad request
         nil
       end
diff --git a/lib/geocoder/lookups/google.rb b/lib/geocoder/lookups/google.rb
index 88764dce..87f56d8f 100644
--- a/lib/geocoder/lookups/google.rb
+++ b/lib/geocoder/lookups/google.rb
@@ -7,7 +7,7 @@ module Geocoder::Lookup
     private # ---------------------------------------------------------------
 
     def result(query, reverse = false)
-      doc = fetch_data(query, reverse)
+      return nil unless doc = fetch_data(query, reverse)
       case doc['status']; when "OK" # OK status implies >0 results
         doc['results'].first
       when "OVER_QUERY_LIMIT"
diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb
index 3d8e112f..dc831c68 100644
--- a/lib/geocoder/lookups/yahoo.rb
+++ b/lib/geocoder/lookups/yahoo.rb
@@ -7,7 +7,7 @@ module Geocoder::Lookup
     private # ---------------------------------------------------------------
 
     def result(query, reverse = false)
-      doc = fetch_data(query, reverse)
+      return nil unless doc = fetch_data(query, reverse)
       if doc = doc['ResultSet'] and doc['Error'] == 0
         doc['Results'].first if doc['Found'] > 0
       else
diff --git a/test/geocoder_test.rb b/test/geocoder_test.rb
index e5514fbf..a75232f1 100644
--- a/test/geocoder_test.rb
+++ b/test/geocoder_test.rb
@@ -37,6 +37,18 @@ class GeocoderTest < Test::Unit::TestCase
     end
   end
 
+  def test_does_not_choke_on_timeout
+    # keep test output clean: suppress timeout warning
+    orig = $VERBOSE; $VERBOSE = nil
+    Geocoder.send(:valid_lookups).each do |l|
+      Geocoder::Configuration.lookup = l
+      assert_nothing_raised do
+        Geocoder.search("timeout")
+      end
+    end
+    $VERBOSE = orig
+  end
+
   def test_distance_to_returns_float
     v = Venue.new(*venue_params(:msg))
     v.latitude, v.longitude = [40.750354, -73.993371]
diff --git a/test/test_helper.rb b/test/test_helper.rb
index a283bb2d..996a868f 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -50,6 +50,7 @@ module Geocoder
     class Google < Base
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
+        raise TimeoutError if query == "timeout"
         file = query == "no results" ? :no_results : :madison_square_garden
         File.read(File.join("test", "fixtures", "google_#{file}.json"))
       end
@@ -58,6 +59,7 @@ module Geocoder
     class Yahoo < Base
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
+        raise TimeoutError if query == "timeout"
         file = query == "no results" ? :no_results : :madison_square_garden
         File.read(File.join("test", "fixtures", "yahoo_#{file}.json"))
       end
@@ -66,6 +68,7 @@ module Geocoder
     class Freegeoip < Base
       private #-----------------------------------------------------------------
       def fetch_raw_data(query, reverse = false)
+        raise TimeoutError if query == "timeout"
         File.read(File.join("test", "fixtures", "freegeoip_74_200_247_59.json"))
       end
     end
-- 
GitLab