From 6509837fc1b2d9aa23a5f8a71044862d458d8f91 Mon Sep 17 00:00:00 2001 From: stve Date: Sun, 1 Mar 2015 22:52:10 -0500 Subject: [PATCH] improved error handling on responses --- lib/instapaper/error.rb | 1 + lib/instapaper/http/request.rb | 16 ++++++++++++-- spec/instapaper/http/request_spec.rb | 31 ++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 spec/instapaper/http/request_spec.rb diff --git a/lib/instapaper/error.rb b/lib/instapaper/error.rb index ddcfd3a..ea524b6 100644 --- a/lib/instapaper/error.rb +++ b/lib/instapaper/error.rb @@ -4,6 +4,7 @@ module Instapaper # @return [Integer] attr_reader :code + ServiceUnavailableError = Class.new(self) BookmarkError = Class.new(self) FolderError = Class.new(self) HighlightError = Class.new(self) diff --git a/lib/instapaper/http/request.rb b/lib/instapaper/http/request.rb index 01022cd..5666fd6 100644 --- a/lib/instapaper/http/request.rb +++ b/lib/instapaper/http/request.rb @@ -41,11 +41,23 @@ module Instapaper @headers = Instapaper::HTTP::Headers.new(@client, @request_method, @uri, @options).request_headers options_key = @request_method == :get ? :params : :form response = ::HTTP.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options) - fail_if_error(parsed_response(response)) + fail_if_error(response, raw) + fail_if_error_in_body(parsed_response(response)) raw ? response.to_s : parsed_response(response) end - def fail_if_error(response) + def fail_if_error(response, raw) + fail Instapaper::Error::ServiceUnavailableError if response.status != 200 + return if raw + + begin + response.parse + rescue JSON::ParserError + fail Instapaper::Error::ServiceUnavailableError + end + end + + def fail_if_error_in_body(response) error = error(response) fail(error) if error end diff --git a/spec/instapaper/http/request_spec.rb b/spec/instapaper/http/request_spec.rb new file mode 100644 index 0000000..8dd3f29 --- /dev/null +++ b/spec/instapaper/http/request_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe Instapaper::HTTP::Request do + let(:client) { Instapaper::Client.new(consumer_key: 'CK', consumer_secret: 'CS', oauth_token: 'OT', oauth_token_secret: 'OS') } + + describe 'error handling' do + context 'when receiving a non-200 response' do + before do + stub_post('/api/1/folders/list') + .to_return(status: 503, body: '', headers: {content_type: 'application/json; charset=utf-8'}) + end + it 'raises a ServiceUnavailableError' do + expect { + client.folders + }.to raise_error(Instapaper::Error::ServiceUnavailableError) + end + end + + context 'when failing to parse json' do + before do + stub_post('/api/1/folders/list') + .to_return(status: 200, body: '{"key":"value}', headers: {content_type: 'application/json; charset=utf-8'}) + end + it 'raises a ServiceUnavailableError' do + expect { + client.folders + }.to raise_error(Instapaper::Error::ServiceUnavailableError) + end + end + end +end