From 4dc3b36e054b328ba2b15bcda3db239c6e9c72c6 Mon Sep 17 00:00:00 2001 From: German Velasco <germsvel@gmail.com> Date: Tue, 16 Jan 2018 16:03:50 -0500 Subject: [PATCH] Raise bing errors for statuses 403, 500, 503 Bing returns the status codes within the json response. When a request is forbidden, it will return a 403. If there is an internal server error, it will return a 500. And if the service is unavailable for some other reason, it will return a 503. That information was obtained from bing's [Status Codes and Error Handling](https://msdn.microsoft.com/en-us/library/ff701703.aspx) documentation. We handle those three status codes here to raise `Geocoder::RequestDenied` (for 403) and `Geocoder::ServiceUnavailable` (for 500 and 503). This allows for the users of the Geocoder to handle those errors in their applications. --- lib/geocoder/lookups/bing.rb | 5 +++++ test/fixtures/bing_forbidden_request | 16 ++++++++++++++++ test/fixtures/bing_internal_server_error | 16 ++++++++++++++++ test/unit/lookups/bing_test.rb | 14 ++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 test/fixtures/bing_forbidden_request create mode 100644 test/fixtures/bing_internal_server_error diff --git a/lib/geocoder/lookups/bing.rb b/lib/geocoder/lookups/bing.rb index 53aaadf5..5d46f3a8 100644 --- a/lib/geocoder/lookups/bing.rb +++ b/lib/geocoder/lookups/bing.rb @@ -44,6 +44,11 @@ module Geocoder::Lookup return doc['resourceSets'].first['estimatedTotal'] > 0 ? doc['resourceSets'].first['resources'] : [] elsif doc['statusCode'] == 401 and doc["authenticationResultCode"] == "InvalidCredentials" raise_error(Geocoder::InvalidApiKey) || Geocoder.log(:warn, "Invalid Bing API key.") + elsif doc['statusCode'] == 403 + raise_error(Geocoder::RequestDenied) || Geocoder.log(:warn, "Bing Geocoding API error: Forbidden Request") + elsif [500, 503].include?(doc['statusCode']) + raise_error(Geocoder::ServiceUnavailable) || + Geocoder.log(:warn, "Bing Geocoding API error: Service Unavailable") else Geocoder.log(:warn, "Bing Geocoding API error: #{doc['statusCode']} (#{doc['statusDescription']}).") end diff --git a/test/fixtures/bing_forbidden_request b/test/fixtures/bing_forbidden_request new file mode 100644 index 00000000..6736e6ab --- /dev/null +++ b/test/fixtures/bing_forbidden_request @@ -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":403, + "statusDescription":"OK", + "traceId":"907b76a307bc49129a489de3d4c992ea|CH1M001463|02.00.82.2800|CH1MSNVM001383, CH1MSNVM001358, CH1MSNVM001397" +} diff --git a/test/fixtures/bing_internal_server_error b/test/fixtures/bing_internal_server_error new file mode 100644 index 00000000..8abd2c4d --- /dev/null +++ b/test/fixtures/bing_internal_server_error @@ -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":500, + "statusDescription":"OK", + "traceId":"907b76a307bc49129a489de3d4c992ea|CH1M001463|02.00.82.2800|CH1MSNVM001383, CH1MSNVM001358, CH1MSNVM001397" +} diff --git a/test/unit/lookups/bing_test.rb b/test/unit/lookups/bing_test.rb index db9457b9..028f8410 100644 --- a/test/unit/lookups/bing_test.rb +++ b/test/unit/lookups/bing_test.rb @@ -82,4 +82,18 @@ class BingTest < GeocoderTestCase l.send(:results, Geocoder::Query.new("service unavailable")) end end + + def test_raises_exception_when_bing_returns_forbidden_request + Geocoder.configure(:always_raise => [Geocoder::RequestDenied]) + assert_raises Geocoder::RequestDenied do + Geocoder.search("forbidden request") + end + end + + def test_raises_exception_when_bing_returns_internal_server_error + Geocoder.configure(:always_raise => [Geocoder::ServiceUnavailable]) + assert_raises Geocoder::ServiceUnavailable do + Geocoder.search("internal server error") + end + end end -- GitLab