faraday 2.7.11 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72fbb1db4fce28541cd53b5908e1fc18539ead8322d0b642069bd2e63d2a6543
4
- data.tar.gz: a5e4f596d8f23e00f064c9789f85fa1cb194cac85168177750b76b3a3e9c7f4d
3
+ metadata.gz: bf63567c6cdd2b98f1046c1f219925f847aa166966c5d95fb95a394e0e7c277a
4
+ data.tar.gz: e9a4839b422aaebcd740ce8d2203accd36f17138b44bd67aa86a9410467c89b3
5
5
  SHA512:
6
- metadata.gz: f880cdd4a42f22ac4eafeab1ddfcfb9e7a8ff0299956a279b207e4ed50d9b86fa09e44e74c4810b9ace3748db5edf6a9f62c73310d09ec1bbf73ec981356d921
7
- data.tar.gz: 159e971ec7168017e0053511217a8b89314cd25aaf626a3a409db800218e39b172741a1264616c7b770a3ce45e9ee9a0bd5f9dc6fd43511cc4b9f8ae5fa8304a
6
+ metadata.gz: 6f5a0d034099cf967dbae0b1bf9d92d3d0291e45a27c2150dae5129f8a634f583223a0273c0491536337bc2cbbe75ce7d89f7967980e48181b48c2b47d93b3a8
7
+ data.tar.gz: d0e48e42fbff20178e7ed20734c52033464e43ca013255dc33e55f42270b75ebba1619b8380dbd0d9a148e5f4159654229cb9b1625028f9cb128b113977b0e40
@@ -146,7 +146,7 @@ module Faraday
146
146
  # which means that all of a path, parameters, and headers must be the same as an actual request.
147
147
  def strict_mode=(value)
148
148
  @strict_mode = value
149
- @stack.each do |_method, stubs|
149
+ @stack.each_value do |stubs|
150
150
  stubs.each do |stub|
151
151
  stub.strict_mode = value
152
152
  end
data/lib/faraday/error.rb CHANGED
@@ -124,6 +124,10 @@ module Faraday
124
124
  class UnprocessableEntityError < ClientError
125
125
  end
126
126
 
127
+ # Raised by Faraday::Response::RaiseError in case of a 429 response.
128
+ class TooManyRequestsError < ClientError
129
+ end
130
+
127
131
  # Faraday server error class. Represents 5xx status responses.
128
132
  class ServerError < Error
129
133
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'pp'
4
-
5
3
  module Faraday
6
4
  module Logging
7
5
  # Serves as an integration point to customize logging
@@ -30,7 +30,7 @@ module Faraday
30
30
  new_value = value
31
31
  end
32
32
 
33
- send("#{key}=", new_value) unless new_value.nil?
33
+ send(:"#{key}=", new_value) unless new_value.nil?
34
34
  end
35
35
  self
36
36
  end
@@ -38,7 +38,7 @@ module Faraday
38
38
  # Public
39
39
  def delete(key)
40
40
  value = send(key)
41
- send("#{key}=", nil)
41
+ send(:"#{key}=", nil)
42
42
  value
43
43
  end
44
44
 
@@ -57,7 +57,7 @@ module Faraday
57
57
  else
58
58
  other_value
59
59
  end
60
- send("#{key}=", new_value) unless new_value.nil?
60
+ send(:"#{key}=", new_value) unless new_value.nil?
61
61
  end
62
62
  self
63
63
  end
@@ -24,7 +24,13 @@ module Faraday
24
24
  private
25
25
 
26
26
  def encode(data)
27
- ::JSON.generate(data)
27
+ if options[:encoder].is_a?(Array) && options[:encoder].size >= 2
28
+ options[:encoder][0].public_send(options[:encoder][1], data)
29
+ elsif options[:encoder].respond_to?(:dump)
30
+ options[:encoder].dump(data)
31
+ else
32
+ ::JSON.generate(data)
33
+ end
28
34
  end
29
35
 
30
36
  def match_content_type(env)
@@ -11,6 +11,8 @@ module Faraday
11
11
  @parser_options = parser_options
12
12
  @content_types = Array(content_type)
13
13
  @preserve_raw = preserve_raw
14
+
15
+ process_parser_options
14
16
  end
15
17
 
16
18
  def on_complete(env)
@@ -27,7 +29,11 @@ module Faraday
27
29
  end
28
30
 
29
31
  def parse(body)
30
- ::JSON.parse(body, @parser_options || {}) unless body.strip.empty?
32
+ return if body.strip.empty?
33
+
34
+ decoder, method_name = @decoder_options
35
+
36
+ decoder.public_send(method_name, body, @parser_options || {})
31
37
  end
32
38
 
33
39
  def parse_response?(env)
@@ -47,6 +53,19 @@ module Faraday
47
53
  type = type.split(';', 2).first if type.index(';')
48
54
  type
49
55
  end
56
+
57
+ def process_parser_options
58
+ @decoder_options = @parser_options&.delete(:decoder)
59
+
60
+ @decoder_options =
61
+ if @decoder_options.is_a?(Array) && @decoder_options.size >= 2
62
+ @decoder_options.slice(0, 2)
63
+ elsif @decoder_options.respond_to?(:load)
64
+ [@decoder_options, :load]
65
+ else
66
+ [::JSON, :parse]
67
+ end
68
+ end
50
69
  end
51
70
  end
52
71
  end
@@ -30,6 +30,8 @@ module Faraday
30
30
  raise Faraday::ConflictError, response_values(env)
31
31
  when 422
32
32
  raise Faraday::UnprocessableEntityError, response_values(env)
33
+ when 429
34
+ raise Faraday::TooManyRequestsError, response_values(env)
33
35
  when ClientErrorStatuses
34
36
  raise Faraday::ClientError, response_values(env)
35
37
  when ServerErrorStatuses
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Faraday
4
- VERSION = '2.7.11'
4
+ VERSION = '2.8.0'
5
5
  end
@@ -132,4 +132,68 @@ RSpec.describe Faraday::Request::Json do
132
132
  expect(result_type).to eq('application/xml; charset=utf-8')
133
133
  end
134
134
  end
135
+
136
+ context 'with encoder' do
137
+ let(:encoder) do
138
+ double('Encoder').tap do |e|
139
+ allow(e).to receive(:dump) { |s, opts| JSON.generate(s, opts) }
140
+ end
141
+ end
142
+
143
+ let(:result) { process(a: 1) }
144
+
145
+ context 'when encoder is passed as object' do
146
+ let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: encoder }) }
147
+
148
+ it 'calls specified JSON encoder\'s dump method' do
149
+ expect(encoder).to receive(:dump).with({ a: 1 })
150
+
151
+ result
152
+ end
153
+
154
+ it 'encodes body' do
155
+ expect(result_body).to eq('{"a":1}')
156
+ end
157
+
158
+ it 'adds content type' do
159
+ expect(result_type).to eq('application/json')
160
+ end
161
+ end
162
+
163
+ context 'when encoder is passed as an object-method pair' do
164
+ let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }, { encoder: [encoder, :dump] }) }
165
+
166
+ it 'calls specified JSON encoder' do
167
+ expect(encoder).to receive(:dump).with({ a: 1 })
168
+
169
+ result
170
+ end
171
+
172
+ it 'encodes body' do
173
+ expect(result_body).to eq('{"a":1}')
174
+ end
175
+
176
+ it 'adds content type' do
177
+ expect(result_type).to eq('application/json')
178
+ end
179
+ end
180
+
181
+ context 'when encoder is not passed' do
182
+ let(:middleware) { described_class.new(->(env) { Faraday::Response.new(env) }) }
183
+
184
+ it 'calls JSON.generate' do
185
+ expect(JSON).to receive(:generate).with({ a: 1 })
186
+
187
+ result
188
+ end
189
+
190
+ it 'encodes body' do
191
+ expect(result_body).to eq('{"a":1}')
192
+ end
193
+
194
+ it 'adds content type' do
195
+ expect(result_type).to eq('application/json')
196
+ end
197
+ end
198
+ end
135
199
  end
@@ -114,4 +114,76 @@ RSpec.describe Faraday::Response::Json, type: :response do
114
114
  expect(response.body).to eq(result)
115
115
  end
116
116
  end
117
+
118
+ context 'with decoder' do
119
+ let(:decoder) do
120
+ double('Decoder').tap do |e|
121
+ allow(e).to receive(:load) { |s, opts| JSON.parse(s, opts) }
122
+ end
123
+ end
124
+
125
+ let(:body) { '{"a": 1}' }
126
+ let(:result) { { a: 1 } }
127
+
128
+ context 'when decoder is passed as object' do
129
+ let(:options) do
130
+ {
131
+ parser_options: {
132
+ decoder: decoder,
133
+ option: :option_value,
134
+ symbolize_names: true
135
+ }
136
+ }
137
+ end
138
+
139
+ it 'passes relevant options to specified decoder\'s load method' do
140
+ expect(decoder).to receive(:load)
141
+ .with(body, { option: :option_value, symbolize_names: true })
142
+ .and_return(result)
143
+
144
+ response = process(body)
145
+ expect(response.body).to eq(result)
146
+ end
147
+ end
148
+
149
+ context 'when decoder is passed as an object-method pair' do
150
+ let(:options) do
151
+ {
152
+ parser_options: {
153
+ decoder: [decoder, :load],
154
+ option: :option_value,
155
+ symbolize_names: true
156
+ }
157
+ }
158
+ end
159
+
160
+ it 'passes relevant options to specified decoder\'s method' do
161
+ expect(decoder).to receive(:load)
162
+ .with(body, { option: :option_value, symbolize_names: true })
163
+ .and_return(result)
164
+
165
+ response = process(body)
166
+ expect(response.body).to eq(result)
167
+ end
168
+ end
169
+
170
+ context 'when decoder is not passed' do
171
+ let(:options) do
172
+ {
173
+ parser_options: {
174
+ symbolize_names: true
175
+ }
176
+ }
177
+ end
178
+
179
+ it 'passes relevant options to JSON parse' do
180
+ expect(JSON).to receive(:parse)
181
+ .with(body, { symbolize_names: true })
182
+ .and_return(result)
183
+
184
+ response = process(body)
185
+ expect(response.body).to eq(result)
186
+ end
187
+ end
188
+ end
117
189
  end
@@ -14,6 +14,7 @@ RSpec.describe Faraday::Response::RaiseError do
14
14
  stub.get('request-timeout') { [408, { 'X-Reason' => 'because' }, 'keep looking'] }
15
15
  stub.get('conflict') { [409, { 'X-Reason' => 'because' }, 'keep looking'] }
16
16
  stub.get('unprocessable-entity') { [422, { 'X-Reason' => 'because' }, 'keep looking'] }
17
+ stub.get('too-many-requests') { [429, { 'X-Reason' => 'because' }, 'keep looking'] }
17
18
  stub.get('4xx') { [499, { 'X-Reason' => 'because' }, 'keep looking'] }
18
19
  stub.get('nil-status') { [nil, { 'X-Reason' => 'nil' }, 'fail'] }
19
20
  stub.get('server-error') { [500, { 'X-Error' => 'bailout' }, 'fail'] }
@@ -113,6 +114,17 @@ RSpec.describe Faraday::Response::RaiseError do
113
114
  end
114
115
  end
115
116
 
117
+ it 'raises Faraday::TooManyRequestsError for 429 responses' do
118
+ expect { conn.get('too-many-requests') }.to raise_error(Faraday::TooManyRequestsError) do |ex|
119
+ expect(ex.message).to eq('the server responded with status 429')
120
+ expect(ex.response[:headers]['X-Reason']).to eq('because')
121
+ expect(ex.response[:status]).to eq(429)
122
+ expect(ex.response_status).to eq(429)
123
+ expect(ex.response_body).to eq('keep looking')
124
+ expect(ex.response_headers['X-Reason']).to eq('because')
125
+ end
126
+ end
127
+
116
128
  it 'raises Faraday::NilStatusError for nil status in response' do
117
129
  expect { conn.get('nil-status') }.to raise_error(Faraday::NilStatusError) do |ex|
118
130
  expect(ex.message).to eq('http status could not be derived from the server response')
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.11
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "@technoweenie"
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-09-12 00:00:00.000000000 Z
13
+ date: 2023-12-20 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: base64
@@ -145,7 +145,7 @@ licenses:
145
145
  - MIT
146
146
  metadata:
147
147
  homepage_uri: https://lostisland.github.io/faraday
148
- changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.7.11
148
+ changelog_uri: https://github.com/lostisland/faraday/releases/tag/v2.8.0
149
149
  source_code_uri: https://github.com/lostisland/faraday
150
150
  bug_tracker_uri: https://github.com/lostisland/faraday/issues
151
151
  post_install_message: