diff --git a/lib/geocoder/lookups/freegeoip.rb b/lib/geocoder/lookups/freegeoip.rb
index dcc5e44f5565ef97cb2d73228a78ab3c55a7af7f..4ae499af6c68b6172c3a350a4f04553e7198f02b 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 88764dceea69be2e0e1de1523b432b1656a6b257..87f56d8f6456eb3027ca1e61452fde256f06d922 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 3d8e112fa0e6da62991eaa86d16c9ff034fe3d8e..dc831c68e01158d2997b10e7cdd046799dfcd0d3 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 e5514fbf9a79a9fe0f513c5d63b5a8e6e8df92ab..a75232f1a534f2d721ae41f710c085cb0de77c68 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 a283bb2db34731835bdf8de6dc4a7026aef423b4..996a868f64fae50d8ea30303a961f70709a6f29f 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