From e3851248505cc4f643d707bfc6724fcb0cdfe1b0 Mon Sep 17 00:00:00 2001
From: Thu Trang Pham <thuutrangpham@gmail.com>
Date: Mon, 26 Jan 2015 21:06:04 -0500
Subject: [PATCH] Handle Bing over limit when header 'X-MS-BM-WS-INFO' is set
 to 1

---
 lib/geocoder/lookups/bing.rb   | 14 ++++++++++++++
 test/fixtures/bing_over_limit  | 16 ++++++++++++++++
 test/test_helper.rb            | 16 +++++++++++++++-
 test/unit/lookups/bing_test.rb |  8 ++++++++
 4 files changed, 53 insertions(+), 1 deletion(-)
 create mode 100644 test/fixtures/bing_over_limit

diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb
index 0149d144..e8849551 100644
--- a/lib/geocoder/lookups/bing.rb
+++ b/lib/geocoder/lookups/bing.rb
@@ -55,5 +55,19 @@ module Geocoder::Lookup
         key: configuration.api_key
       }.merge(super)
     end
+
+    def check_response_for_errors!(response)
+      super
+      puts response
+      if response.headers['X-MS-BM-WS-INFO'] == 1
+        # Occasionally, the servers processing service requests can be overloaded, 
+        # and you may receive some responses that contain no results for queries that 
+        # you would normally receive a result. To identify this situation, 
+        # check the HTTP headers of the response. If the HTTP header X-MS-BM-WS-INFO is set to 1, 
+        # it is best to wait a few seconds and try again.
+        raise_error(Geocoder::OverQueryLimitError) ||
+          warn("Bing Geocoding API error: Service Requests Overloaded")
+      end   
+    end
   end
 end
diff --git a/test/fixtures/bing_over_limit b/test/fixtures/bing_over_limit
new file mode 100644
index 00000000..43135d61
--- /dev/null
+++ b/test/fixtures/bing_over_limit
@@ -0,0 +1,16 @@
+{
+   "authenticationResultCode":"ValidCredentials",
+   "brandLogoUri":"http:\/\/dev.virtualearth.net\/Branding\/logo_powered_by.png",
+   "copyright":"Copyright © 2011 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.",
+   "resourceSets":[
+      {
+         "estimatedTotal":0,
+         "resources":[
+
+         ]
+      }
+   ],
+   "statusCode":200,
+   "statusDescription":"OK",
+   "traceId":"907b76a307bc49129a489de3d4c992ea|CH1M001463|02.00.82.2800|CH1MSNVM001383, CH1MSNVM001358, CH1MSNVM001397"
+}
diff --git a/test/test_helper.rb b/test/test_helper.rb
index fa73e12b..5ee0ede2 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -118,6 +118,19 @@ module Geocoder
       end
     end
 
+    class Bing
+      private
+      def read_fixture(file)
+        if file == "bing_over_limit"
+          filepath = File.join("test", "fixtures", file)
+          s = File.read(filepath).strip.gsub(/\n\s*/, "")
+          MockHttpResponse.new(body: s, code: "200", headers: {'X-MS-BM-WS-INFO' => 1})
+        else
+          super
+        end
+      end
+    end
+
     class GooglePremier
       private
       def fixture_prefix
@@ -411,10 +424,11 @@ class GeocoderTestCase < Test::Unit::TestCase
 end
 
 class MockHttpResponse
-  attr_reader :code, :body
+  attr_reader :code, :body, :headers
   def initialize(options = {})
     @code = options[:code].to_s
     @body = options[:body]
+    @headers = options[:headers] || {}
   end
 
   def [](key)
diff --git a/test/unit/lookups/bing_test.rb b/test/unit/lookups/bing_test.rb
index 9a63f90e..f7c98846 100644
--- a/test/unit/lookups/bing_test.rb
+++ b/test/unit/lookups/bing_test.rb
@@ -65,4 +65,12 @@ class BingTest < GeocoderTestCase
     assert_match(/Locations\/uk\?q=manchester,%20lancashire/, url)
     assert_no_match(/query/, url)
   end
+
+  def test_raises_exception_when_service_request_overloaded
+    Geocoder.configure(:always_raise => [Geocoder::OverQueryLimitError])
+    l = Geocoder::Lookup.get(:bing)
+    assert_raises Geocoder::OverQueryLimitError do
+      l.send(:results, Geocoder::Query.new("over limit"))
+    end
+  end
 end
-- 
GitLab