From 5a6416869545c57b425ec1a819c1e2723a693079 Mon Sep 17 00:00:00 2001
From: Alex Reisner <alex@alexreisner.com>
Date: Fri, 21 Dec 2012 14:44:32 -0500
Subject: [PATCH] Raise exceptions for Yahoo API errors.

---
 lib/geocoder/lookups/yahoo.rb        | 17 +++++++++++++++++
 test/fixtures/yahoo_invalid_key.json |  2 ++
 test/fixtures/yahoo_over_limit.json  |  2 ++
 test/services_test.rb                | 15 +++++++++++++++
 test/test_helper.rb                  |  2 ++
 5 files changed, 38 insertions(+)
 create mode 100644 test/fixtures/yahoo_invalid_key.json
 create mode 100644 test/fixtures/yahoo_over_limit.json

diff --git a/lib/geocoder/lookups/yahoo.rb b/lib/geocoder/lookups/yahoo.rb
index 43138b62..77a658b4 100644
--- a/lib/geocoder/lookups/yahoo.rb
+++ b/lib/geocoder/lookups/yahoo.rb
@@ -34,6 +34,23 @@ module Geocoder::Lookup
       end
     end
 
+    ##
+    # Yahoo returns errors as XML even when JSON format is specified.
+    # Handle that here, without parsing the XML
+    # (which would add unnecessary complexity).
+    #
+    def parse_raw_data(raw_data)
+      if raw_data.match /^<\?xml/
+        if raw_data.include?("Rate Limit Exceeded")
+          raise_error(Geocoder::OverQueryLimitError) || warn("Over API query limit.")
+        elsif raw_data.include?("Please provide valid credentials")
+          raise_error(Geocoder::InvalidApiKey) || warn("Invalid API key.")
+        end
+      else
+        super(raw_data)
+      end
+    end
+
     def query_url_params(query)
       super.merge(
         :location => query.sanitized_text,
diff --git a/test/fixtures/yahoo_invalid_key.json b/test/fixtures/yahoo_invalid_key.json
new file mode 100644
index 00000000..c9b7319b
--- /dev/null
+++ b/test/fixtures/yahoo_invalid_key.json
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>\n<yahoo:error xmlns:yahoo='http://yahooapis.com/v1/base.rng'\n  xml:lang='en-US'>
+  <yahoo:description>Please provide valid credentials. OAuth oauth_problem="consumer_key_unknown", realm="yahooapis.com"</yahoo:description>\n</yahoo:error>
diff --git a/test/fixtures/yahoo_over_limit.json b/test/fixtures/yahoo_over_limit.json
new file mode 100644
index 00000000..7dddadf5
--- /dev/null
+++ b/test/fixtures/yahoo_over_limit.json
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?> <yahoo:error xmlns:yahoo="http://yahooapis.com/v1/base.rng\ <http://yahooapis.com/v1/base.rng%5C>" xml:lang="en-US"> 
+          <yahoo:description>Rate Limit Exceeded</yahoo:description> <yahoo:detail>Key has exceeded its configured rate limit.</yahoo:detail> </yahoo:error>
diff --git a/test/services_test.rb b/test/services_test.rb
index 200e10e7..3681c018 100644
--- a/test/services_test.rb
+++ b/test/services_test.rb
@@ -105,6 +105,21 @@ class ServicesTest < Test::Unit::TestCase
     assert_equal "Madison Square Garden, New York, NY 10001, United States", result.address
   end
 
+  def test_yahoo_raises_exception_when_over_query_limit
+    Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
+    l = Geocoder::Lookup.get(:yahoo)
+    assert_raises Geocoder::OverQueryLimitError do
+      l.send(:results, Geocoder::Query.new("over limit"))
+    end
+  end
+
+  def test_yahoo_raises_exception_on_invalid_key
+    Geocoder.configure(:always_raise => [Geocoder::InvalidApiKey])
+    l = Geocoder::Lookup.get(:yahoo)
+    assert_raises Geocoder::InvalidApiKey do
+      l.send(:results, Geocoder::Query.new("invalid key"))
+    end
+  end
 
   # --- Yandex ---
 
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 95b7dedb..f1b526c1 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -110,6 +110,8 @@ module Geocoder
         raise SocketError if query.text == "socket_error"
         file = case query.text
           when "no results"; :no_results
+          when "over limit"; :over_limit
+          when "invalid key"; :invalid_key
           when "error";      :error
           else               :madison_square_garden
         end
-- 
GitLab