Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ end

If the client is unable to connect to GoCardless, an appropriate exception will be raised, for example:

* `Faraday::TimeoutError`, in case of a timeout
* `Faraday::TimeoutError`, in case of a timeout (requests time out after 60 seconds by default; change this with the `connection_options` client option, e.g. `connection_options: { request: { timeout: 10 } }`)
* `Faraday::ConnectionFailed`, in case of a connection issue (e.g. problems with DNS resolution)
* `GoCardlessPro::ApiError`, for `5xx` errors returned from our infrastructure, but not by the API itself

Expand Down
6 changes: 5 additions & 1 deletion lib/gocardless_pro/api_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
module GoCardlessPro
# GoCardless API
class ApiService
# Seconds to wait for a response when `connection_options` doesn't set `request: { timeout: ... }`
DEFAULT_TIMEOUT = 60

attr_reader :on_idempotency_conflict

# Initialize an APIService
Expand All @@ -22,8 +25,9 @@ def initialize(url, token, options = {})
root_url, @path_prefix = unpack_url(url)
http_adapter = options[:http_adapter] || [:net_http]
connection_options = options.fetch(:connection_options, {})
request_options = { timeout: DEFAULT_TIMEOUT }.merge(connection_options.fetch(:request, {}))

@connection = Faraday.new(root_url, connection_options) do |faraday|
@connection = Faraday.new(root_url, connection_options.merge(request: request_options)) do |faraday|
faraday.response :raise_gocardless_errors

faraday.adapter(*http_adapter)
Expand Down
2 changes: 1 addition & 1 deletion lib/gocardless_pro/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ def webhooks
# @option options [Symbol] :environment the environment to connect to - one of `:live` or `:sandbox`.
# @option options [Symbol] :access_token the API token
# @option options [Symbol] :url the full URL used to make requests to. If you specify this, it will be used over the `environment` option.
# @option options [Symbol] :connection_options `Faraday` connection options hash, e.g. `{ request: { timeout: 3 } }`.
# @option options [Symbol] :connection_options `Faraday` connection options hash, e.g. `{ request: { timeout: 3 } }`. Requests time out after 60 seconds unless `request: { timeout: ... }` is set.
# @return [Client] A client configured to use the API with HTTP Basic
# authentication.
#
Expand Down
26 changes: 26 additions & 0 deletions spec/api_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,32 @@
}
end

describe 'request timeout' do
let(:connection) { service.instance_variable_get(:@connection) }

it 'defaults to 60 seconds' do
expect(GoCardlessPro::ApiService::DEFAULT_TIMEOUT).to eq(60)
expect(connection.options.timeout).to eq(60)
end

context 'when connection_options sets a timeout' do
let(:options) { { connection_options: { request: { timeout: 5 } } } }

it 'uses the configured timeout' do
expect(connection.options.timeout).to eq(5)
end
end

context 'when connection_options sets other request options' do
let(:options) { { connection_options: { request: { open_timeout: 2 } } } }

it 'keeps the default timeout' do
expect(connection.options.timeout).to eq(60)
expect(connection.options.open_timeout).to eq(2)
end
end
end

it 'uses basic auth' do
stub = stub_request(:get, 'https://api.example.com/customers').
with(headers: { 'Authorization' => 'Bearer secret_token' }).
Expand Down
Loading