faraday-retry 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4c985b60e619c7a2161b8643fda86adcd4927847a66d903bbc22a32ed851d13
4
- data.tar.gz: 010d8a002a7310f82c44395344cc81cb3f8acfe9e53ca8aae8ae84cd3b66d90a
3
+ metadata.gz: af805c058f1e08fba4ab4c53587f88906f086f06bda02dd4daf578123d6aa79f
4
+ data.tar.gz: 714eeaadf0d8021d7c33f86ece4dda66366fcc6525e8bf395c3e71591d0a8bc2
5
5
  SHA512:
6
- metadata.gz: b6dc78fe8c3b3ccc189c086271eb646e06f6e598a0a2b311ce3f0831321ba8f00b01d24be1c29521f7bbef5367eb17c43be7f6dfaa6402f0ec9cf206483f8794
7
- data.tar.gz: 6338884c1806a7d06f33457db3939d71aaf761c9cc8c427a14c68257600d0601ff6765dde9b061254fd5af8f4ff77315d018a8d42d5326842fd0d26d0e52219f
6
+ metadata.gz: 6de30437afefef5b6887a0c7b2e72615775b63a92aaee63c37672631d9e09011b0b46fa9c208e6ca280d55ace287e12c9077ed18107968bc5593255cd028b6c1
7
+ data.tar.gz: dc0e7f4b11e714addd9a11426cc5071eb2245ea8f5cb24a38e7f63ee50030df81b14380912b4f0b786f9bfa53dfeccbc16f802337638054d7e36ad56be667f3f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ _nothing yet_
6
+
7
+ ## v2.2.1 (2024-04-15)
8
+
9
+ * Avoid deprecation warning about ::UploadIO constant when used without faraday-multipart gem [PR #37](https://github.com/lostisland/faraday-retry/pull/37) [@iMacTia]
10
+ * Documentation update [PR #30](https://github.com/lostisland/faraday-retry/pull/30) [@olleolleolle]
11
+ * Documentation update [PR #32](https://github.com/lostisland/faraday-retry/pull/32) Thanks, [@Drowze]!
12
+
3
13
  ## v2.2.0 (2023-06-01)
4
14
 
5
15
  * Support new `header_parser_block` option. [PR #28](https://github.com/lostisland/faraday-retry/pull/28). Thanks, [@zavan]!
@@ -34,3 +44,6 @@ This release consists of the same middleware that was previously bundled with Fa
34
44
  [@maxprokopiev]: https://github.com/maxprokopiev
35
45
  [@brookemckim]: https://github.com/brookemckim
36
46
  [@zavan]: https://github.com/zavan
47
+ [@Drowze]: https://github.com/Drowze
48
+ [@olleolleolle]: https://github.com/olleolleolle
49
+ [@iMacTia]: https://github.com/iMacTia
data/README.md CHANGED
@@ -75,7 +75,7 @@ retry_options = {
75
75
  #### Specify which exceptions should trigger a retry
76
76
 
77
77
  You can provide an `exceptions` option with a list of exceptions that will replace
78
- the default list of network-related exceptions: `Errno::ETIMEDOUT`, `Timeout::Error`, `Faraday::TimeoutError`.
78
+ the default exceptions: `Errno::ETIMEDOUT`, `Timeout::Error`, `Faraday::TimeoutError`, `Faraday::Error::RetriableResponse`.
79
79
  This can be particularly useful when combined with the [RaiseError][raise_error] middleware.
80
80
 
81
81
  ```ruby
@@ -84,6 +84,14 @@ retry_options = {
84
84
  }
85
85
  ```
86
86
 
87
+ If you want to inherit default exceptions, do it this way.
88
+
89
+ ```ruby
90
+ retry_options = {
91
+ exceptions: Faraday::Retry::Middleware::DEFAULT_EXCEPTIONS + [Faraday::ResourceNotFound, Faraday::UnauthorizedError]
92
+ }
93
+ ```
94
+
87
95
  #### Specify on which response statuses to retry
88
96
 
89
97
  By default the `Retry` middleware will only retry the request if one of the expected exceptions arise.
@@ -141,13 +149,11 @@ retry_options = {
141
149
 
142
150
  ### Call a block on every retry
143
151
 
144
- You can specify a proc object through the `retry_block` option that will be called before every
145
- retry, before There are many different applications for this feature, spacing from instrumentation to monitoring.
146
-
152
+ You can specify a proc object through the `retry_block` option that will be called before every retry.
153
+ There are many different applications for this feature, ranging from instrumentation to monitoring.
147
154
 
148
155
  The block is passed keyword arguments with contextual information: Request environment, middleware options, current number of retries, exception, and amount of time we will wait before retrying. (retry_block is called before the wait time happens)
149
156
 
150
-
151
157
  For example, you might want to keep track of the response statuses:
152
158
 
153
159
  ```ruby
@@ -157,6 +163,27 @@ retry_options = {
157
163
  }
158
164
  ```
159
165
 
166
+ ### Call a block after retries have been exhausted
167
+
168
+ You can specify a lambda object through the `exhausted_retries_block` option that will be called after all retries are exhausted.
169
+ This block will be called once.
170
+
171
+ The block is passed keyword arguments with contextual information and passed your data:
172
+ * Request environment,
173
+ * exception,
174
+ * middleware options
175
+ * and your data.
176
+
177
+ In a lambda you can pass any logic for further work.
178
+
179
+ For example, you might want to update user by request query.
180
+
181
+ ```ruby
182
+ retry_options = {
183
+ exhausted_retries_block: -> (user_id:, env:, exception:, options:) { User.find_by!(id: user_id).do_admin! }
184
+ }
185
+ ```
186
+
160
187
  ## Development
161
188
 
162
189
  After checking out the repo, run `bin/setup` to install dependencies.
@@ -177,4 +204,4 @@ Bug reports and pull requests are welcome on [GitHub](https://github.com/lostisl
177
204
 
178
205
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
179
206
 
180
- [raise_error]: https://lostisland.github.io/faraday/middleware/raise-error
207
+ [raise_error]: https://lostisland.github.io/faraday/#/middleware/included/raising-errors
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'retryable'
4
+
3
5
  module Faraday
4
6
  module Retry
5
7
  # This class provides the main implementation for your middleware.
@@ -15,6 +17,8 @@ module Faraday
15
17
  # (see "retry" middleware: https://github.com/lostisland/faraday/blob/main/lib/faraday/request/retry.rb#L142).
16
18
  # IMPORTANT: Remember to call `@app.call(env)` or `super` to not interrupt the middleware chain!
17
19
  class Middleware < Faraday::Middleware
20
+ include Retryable
21
+
18
22
  DEFAULT_EXCEPTIONS = [
19
23
  Errno::ETIMEDOUT, 'Timeout::Error',
20
24
  Faraday::TimeoutError, Faraday::RetriableResponse
@@ -27,7 +31,8 @@ module Faraday
27
31
  :backoff_factor, :exceptions,
28
32
  :methods, :retry_if, :retry_block,
29
33
  :retry_statuses, :rate_limit_retry_header,
30
- :rate_limit_reset_header, :header_parser_block)
34
+ :rate_limit_reset_header, :header_parser_block,
35
+ :exhausted_retries_block)
31
36
 
32
37
  DEFAULT_CHECK = ->(_env, _exception) { false }
33
38
 
@@ -78,6 +83,10 @@ module Faraday
78
83
  def retry_statuses
79
84
  Array(self[:retry_statuses] ||= [])
80
85
  end
86
+
87
+ def exhausted_retries_block
88
+ self[:exhausted_retries_block] ||= proc {}
89
+ end
81
90
  end
82
91
 
83
92
  # @param app [#call]
@@ -95,8 +104,8 @@ module Faraday
95
104
  # 'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse])
96
105
  # The list of exceptions to handle. Exceptions can be given as
97
106
  # Class, Module, or String.
98
- # @option options [Array] :methods (the idempotent HTTP methods
99
- # in IDEMPOTENT_METHODS) A list of HTTP methods to retry without
107
+ # @option options [Array<Symbol>] :methods (the idempotent HTTP methods
108
+ # in IDEMPOTENT_METHODS) A list of HTTP methods, as symbols, to retry without
100
109
  # calling retry_if. Pass an empty Array to call retry_if
101
110
  # for all exceptions.
102
111
  # @option options [Block] :retry_if (false) block that will receive
@@ -124,6 +133,13 @@ module Faraday
124
133
  # the the value of the retry header and should return the number of
125
134
  # seconds to wait before retrying the request. This is useful if the
126
135
  # value of the header is not a number of seconds or a RFC 2822 formatted date.
136
+ # @option options [Block] :exhausted_retries_block block will receive
137
+ # when all attempts are exhausted. The block will be yielded keyword arguments:
138
+ # * env [Faraday::Env]: Request environment
139
+ # * exception [Exception]: exception that triggered the retry,
140
+ # will be the synthetic `Faraday::RetriableResponse` if the
141
+ # retry was triggered by something other than an exception.
142
+ # * options [Faraday::Options]: middleware options
127
143
  def initialize(app, options = nil)
128
144
  super(app)
129
145
  @options = Options.from(options)
@@ -147,32 +163,14 @@ module Faraday
147
163
  def call(env)
148
164
  retries = @options.max
149
165
  request_body = env[:body]
150
- begin
166
+
167
+ with_retries(env: env, options: @options, retries: retries, body: request_body, errmatch: @errmatch) do
151
168
  # after failure env[:body] is set to the response body
152
169
  env[:body] = request_body
170
+
153
171
  @app.call(env).tap do |resp|
154
172
  raise Faraday::RetriableResponse.new(nil, resp) if @options.retry_statuses.include?(resp.status)
155
173
  end
156
- rescue @errmatch => e
157
- if retries.positive? && retry_request?(env, e)
158
- retries -= 1
159
- rewind_files(request_body)
160
- if (sleep_amount = calculate_sleep_amount(retries + 1, env))
161
- @options.retry_block.call(
162
- env: env,
163
- options: @options,
164
- retry_count: @options.max - (retries + 1),
165
- exception: e,
166
- will_retry_in: sleep_amount
167
- )
168
- sleep sleep_amount
169
- retry
170
- end
171
- end
172
-
173
- raise unless e.is_a?(Faraday::RetriableResponse)
174
-
175
- e.response
176
174
  end
177
175
  end
178
176
 
@@ -209,11 +207,11 @@ module Faraday
209
207
  end
210
208
 
211
209
  def rewind_files(body)
212
- return unless defined?(UploadIO)
210
+ return unless defined?(Faraday::UploadIO)
213
211
  return unless body.is_a?(Hash)
214
212
 
215
213
  body.each do |_, value|
216
- value.rewind if value.is_a?(UploadIO)
214
+ value.rewind if value.is_a?(Faraday::UploadIO)
217
215
  end
218
216
  end
219
217
 
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Adds the ability to retry a request based on settings and errors that have occurred.
4
+ module Retryable
5
+ def with_retries(env:, options:, retries:, body:, errmatch:)
6
+ yield
7
+ rescue errmatch => e
8
+ exhausted_retries(options, env, e) if retries_zero?(retries, env, e)
9
+
10
+ if retries.positive? && retry_request?(env, e)
11
+ retries -= 1
12
+ rewind_files(body)
13
+ if (sleep_amount = calculate_sleep_amount(retries + 1, env))
14
+ options.retry_block.call(
15
+ env: env,
16
+ options: options,
17
+ retry_count: options.max - (retries + 1),
18
+ exception: e,
19
+ will_retry_in: sleep_amount
20
+ )
21
+ sleep sleep_amount
22
+ retry
23
+ end
24
+ end
25
+
26
+ raise unless e.is_a?(Faraday::RetriableResponse)
27
+
28
+ e.response
29
+ end
30
+
31
+ private
32
+
33
+ def retries_zero?(retries, env, exception)
34
+ retries.zero? && retry_request?(env, exception)
35
+ end
36
+
37
+ def exhausted_retries(options, env, exception)
38
+ options.exhausted_retries_block.call(
39
+ env: env,
40
+ exception: exception,
41
+ options: options
42
+ )
43
+ end
44
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Faraday
4
4
  module Retry
5
- VERSION = '2.2.0'
5
+ VERSION = '2.3.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday-retry
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mattia Giuffrida
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-06-01 00:00:00.000000000 Z
11
+ date: 2025-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -151,17 +151,18 @@ files:
151
151
  - lib/faraday/retriable_response.rb
152
152
  - lib/faraday/retry.rb
153
153
  - lib/faraday/retry/middleware.rb
154
+ - lib/faraday/retry/retryable.rb
154
155
  - lib/faraday/retry/version.rb
155
156
  homepage: https://github.com/lostisland/faraday-retry
156
157
  licenses:
157
158
  - MIT
158
159
  metadata:
159
160
  bug_tracker_uri: https://github.com/lostisland/faraday-retry/issues
160
- changelog_uri: https://github.com/lostisland/faraday-retry/blob/v2.2.0/CHANGELOG.md
161
- documentation_uri: http://www.rubydoc.info/gems/faraday-retry/2.2.0
161
+ changelog_uri: https://github.com/lostisland/faraday-retry/blob/v2.3.0/CHANGELOG.md
162
+ documentation_uri: http://www.rubydoc.info/gems/faraday-retry/2.3.0
162
163
  homepage_uri: https://github.com/lostisland/faraday-retry
163
164
  source_code_uri: https://github.com/lostisland/faraday-retry
164
- post_install_message:
165
+ post_install_message:
165
166
  rdoc_options: []
166
167
  require_paths:
167
168
  - lib
@@ -180,7 +181,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
181
  version: '0'
181
182
  requirements: []
182
183
  rubygems_version: 3.1.6
183
- signing_key:
184
+ signing_key:
184
185
  specification_version: 4
185
186
  summary: Catches exceptions and retries each request a limited number of times
186
187
  test_files: []