From c9a9b876fcc8795a69f4e705b14700da49754c0b Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 24 Jun 2022 07:15:09 -0700 Subject: [PATCH] Rescue Faraday::TimeoutError (#604) * Rescue Faraday::TimeoutError If Faraday hits a timeout, it will raise a `Faraday::TimeoutError`. Re-raise this as an `OAuth2::ConnectionError`, reusing the logic in https://github.com/oauth-xx/oauth2/pull/549. This came up in https://github.com/omniauth/omniauth-oauth2/pull/129. * Break out OAuth2::Client#request This resolves several Rubocop lint errors. --- lib/oauth2/client.rb | 32 ++++++++++++++++++++------------ spec/oauth2/client_spec.rb | 28 +++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 17 deletions(-) diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb index 50315603..28368e4c 100644 --- a/lib/oauth2/client.rb +++ b/lib/oauth2/client.rb @@ -5,6 +5,8 @@ module OAuth2 ConnectionError = Class.new(Faraday::ConnectionFailed) + TimeoutError = Class.new(Faraday::TimeoutError) + # The OAuth2::Client class class Client # rubocop:disable Metrics/ClassLength RESERVED_PARAM_KEYS = %w[headers parse].freeze @@ -108,18 +110,7 @@ def token_url(params = nil) # @option opts [Symbol] :parse @see Response::initialize # @yield [req] The Faraday request def request(verb, url, opts = {}) - url = connection.build_url(url).to_s - - begin - response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req| - req.params.update(opts[:params]) if opts[:params] - yield(req) if block_given? - end - rescue Faraday::ConnectionFailed => e - raise ConnectionError, e - end - - response = Response.new(response, parse: opts[:parse]) + response = execute_request(verb, url, opts) case response.status when 301, 302, 303, 307 @@ -251,6 +242,23 @@ def redirection_params private + def execute_request(verb, url, opts = {}) + url = connection.build_url(url).to_s + + begin + response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req| + req.params.update(opts[:params]) if opts[:params] + yield(req) if block_given? + end + rescue Faraday::ConnectionFailed => e + raise ConnectionError, e + rescue Faraday::TimeoutError => e + raise TimeoutError, e + end + + Response.new(response, parse: opts[:parse]) + end + # Returns the authenticator object # # @return [Authenticator] the initialized Authenticator diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb index d87a83e2..f15ae1bc 100644 --- a/spec/oauth2/client_spec.rb +++ b/spec/oauth2/client_spec.rb @@ -431,17 +431,35 @@ context 'when errors are raised by Faraday' do let(:connection) { instance_double(Faraday::Connection, build_url: double) } - it 'rescues Faraday::ConnectionFailed' do + before do allow(connection).to( - receive(:run_request).and_raise(Faraday::ConnectionFailed.new('fail')) + receive(:run_request).and_raise(faraday_exception) ) allow(subject).to receive(:connection).and_return(connection) # rubocop:disable RSpec/SubjectStub + end - expect { subject.request(:get, '/redirect') }.to raise_error do |e| - expect(e.class).to eq(OAuth2::ConnectionError) - expect(e.message).to eq('fail') + shared_examples 'failed connection handler' do + it 'rescues the exception' do + expect { subject.request(:get, '/redirect') }.to raise_error do |e| + expect(e.class).to eq(expected_exception) + expect(e.message).to eq(faraday_exception.message) + end end end + + context 'with Faraday::ConnectionFailed' do + let(:faraday_exception) { Faraday::ConnectionFailed.new('fail') } + let(:expected_exception) { OAuth2::ConnectionError } + + it_behaves_like 'failed connection handler' + end + + context 'with Faraday::TimeoutError' do + let(:faraday_exception) { Faraday::TimeoutError.new('timeout') } + let(:expected_exception) { OAuth2::TimeoutError } + + it_behaves_like 'failed connection handler' + end end end