Skip to content

Commit 00557cf

Browse files
committed
Refactor API client to reduce duplication
1 parent 5287bfd commit 00557cf

File tree

1 file changed

+37
-83
lines changed

1 file changed

+37
-83
lines changed

updater/lib/dependabot/api_client.rb

Lines changed: 37 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ class ApiClient # rubocop:disable Metrics/ClassLength
2424

2525
MAX_REQUEST_RETRIES = 3
2626
INVALID_REQUEST_MSG = /The request contains invalid or unauthorized changes/
27+
NETWORK_ERRORS_TO_RESCUE_FROM = [
28+
HTTP::ConnectionError,
29+
OpenSSL::SSL::SSLError
30+
].freeze
2731

2832
sig { params(base_url: String, job_id: T.any(String, Integer), job_token: String).void }
2933
def initialize(base_url, job_id, job_token)
@@ -49,7 +53,7 @@ def create_pull_request(dependency_change, base_commit_sha)
4953
elsif response.code >= 400
5054
raise ApiError, response.body
5155
end
52-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
56+
rescue *NETWORK_ERRORS_TO_RESCUE_FROM
5357
retry_count ||= 0
5458
retry_count += 1
5559
raise if retry_count > MAX_REQUEST_RETRIES
@@ -76,15 +80,7 @@ def update_pull_request(dependency_change, base_commit_sha)
7680
"base-commit-sha": base_commit_sha
7781
}
7882
}
79-
response = http_client.post(api_url, json: body)
80-
raise ApiError, response.body if response.code >= 400
81-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
82-
retry_count ||= 0
83-
retry_count += 1
84-
raise if retry_count > MAX_REQUEST_RETRIES
85-
86-
sleep(rand(3.0..10.0))
87-
retry
83+
send_http_request_with_retries(:post, api_url, body)
8884
end
8985
end
9086

@@ -96,15 +92,7 @@ def close_pull_request(dependency_names, reason)
9692

9793
api_url = "#{base_url}/update_jobs/#{job_id}/close_pull_request"
9894
body = { data: { "dependency-names": dependency_names, reason: reason } }
99-
response = http_client.post(api_url, json: body)
100-
raise ApiError, response.body if response.code >= 400
101-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
102-
retry_count ||= 0
103-
retry_count += 1
104-
raise if retry_count > MAX_REQUEST_RETRIES
105-
106-
sleep(rand(3.0..10.0))
107-
retry
95+
send_http_request_with_retries(:post, api_url, body)
10896
end
10997
end
11098

@@ -123,15 +111,7 @@ def record_update_job_error(error_type:, error_details:)
123111
"error-details": error_details
124112
}
125113
}
126-
response = http_client.post(api_url, json: body)
127-
raise ApiError, response.body if response.code >= 400
128-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
129-
retry_count ||= 0
130-
retry_count += 1
131-
raise if retry_count > MAX_REQUEST_RETRIES
132-
133-
sleep(rand(3.0..10.0))
134-
retry
114+
send_http_request_with_retries(:post, api_url, body)
135115
end
136116
end
137117

@@ -158,15 +138,7 @@ def record_update_job_warning(warn_type:, warn_title:, warn_description:)
158138
"warn-description": warn_description
159139
}
160140
}
161-
response = http_client.post(api_url, json: body)
162-
raise ApiError, response.body if response.code >= 400
163-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
164-
retry_count ||= 0
165-
retry_count += 1
166-
raise if retry_count > MAX_REQUEST_RETRIES
167-
168-
sleep(rand(3.0..10.0))
169-
retry
141+
send_http_request_with_retries(:post, api_url, body)
170142
end
171143
end
172144

@@ -187,15 +159,7 @@ def record_update_job_unknown_error(error_type:, error_details:)
187159
"error-details": error_details
188160
}
189161
}
190-
response = http_client.post(api_url, json: body)
191-
raise ApiError, response.body if response.code >= 400
192-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
193-
retry_count ||= 0
194-
retry_count += 1
195-
raise if retry_count > MAX_REQUEST_RETRIES
196-
197-
sleep(rand(3.0..10.0))
198-
retry
162+
send_http_request_with_retries(:post, api_url, body)
199163
end
200164
end
201165

@@ -207,15 +171,7 @@ def mark_job_as_processed(base_commit_sha)
207171

208172
api_url = "#{base_url}/update_jobs/#{job_id}/mark_as_processed"
209173
body = { data: { "base-commit-sha": base_commit_sha } }
210-
response = http_client.patch(api_url, json: body)
211-
raise ApiError, response.body if response.code >= 400
212-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
213-
retry_count ||= 0
214-
retry_count += 1
215-
raise if retry_count > MAX_REQUEST_RETRIES
216-
217-
sleep(rand(3.0..10.0))
218-
retry
174+
send_http_request_with_retries(:patch, api_url, body)
219175
end
220176
end
221177

@@ -231,15 +187,7 @@ def update_dependency_list(dependencies, dependency_files)
231187
dependency_files: dependency_files
232188
}
233189
}
234-
response = http_client.post(api_url, json: body)
235-
raise ApiError, response.body if response.code >= 400
236-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
237-
retry_count ||= 0
238-
retry_count += 1
239-
raise if retry_count > MAX_REQUEST_RETRIES
240-
241-
sleep(rand(3.0..10.0))
242-
retry
190+
send_http_request_with_retries(:post, api_url, body)
243191
end
244192
end
245193

@@ -252,15 +200,7 @@ def create_dependency_submission(dependency_submission)
252200
body = {
253201
data: dependency_submission
254202
}
255-
response = http_client.post(api_url, json: body)
256-
raise ApiError, response.body if response.code >= 400
257-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
258-
retry_count ||= 0
259-
retry_count += 1
260-
raise if retry_count > MAX_REQUEST_RETRIES
261-
262-
sleep(rand(3.0..10.0))
263-
retry
203+
send_http_request_with_retries(:post, api_url, body)
264204
end
265205
end
266206

@@ -271,15 +211,7 @@ def record_ecosystem_versions(ecosystem_versions)
271211
body = {
272212
data: { ecosystem_versions: ecosystem_versions }
273213
}
274-
response = http_client.post(api_url, json: body)
275-
raise ApiError, response.body if response.code >= 400
276-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
277-
retry_count ||= 0
278-
retry_count += 1
279-
raise if retry_count > MAX_REQUEST_RETRIES
280-
281-
sleep(rand(3.0..10.0))
282-
retry
214+
send_http_request_with_retries(:post, api_url, body)
283215
end
284216
end
285217

@@ -302,7 +234,7 @@ def increment_metric(metric, tags:)
302234
response = http_client.post(api_url, json: body)
303235
# We treat metrics as fire-and-forget, so just warn if they fail.
304236
Dependabot.logger.debug("Unable to report metric '#{metric}'.") if response.code >= 400
305-
rescue HTTP::ConnectionError, OpenSSL::SSL::SSLError
237+
rescue *NETWORK_ERRORS_TO_RESCUE_FROM
306238
Dependabot.logger.debug("Unable to report metric '#{metric}'.")
307239
end
308240
end
@@ -404,6 +336,28 @@ def record_cooldown_meta(job)
404336

405337
private
406338

339+
sig do
340+
params(
341+
request_type: T.any(Symbol, String),
342+
api_url: String,
343+
json: T::Hash[T.untyped, T.untyped]
344+
).void
345+
end
346+
def send_http_request_with_retries(request_type, api_url, json)
347+
retry_count ||= 0
348+
349+
begin
350+
response = http_client.public_send(request_type, api_url, json: json)
351+
raise ApiError, response.body if response.code >= 400
352+
rescue *NETWORK_ERRORS_TO_RESCUE_FROM => e
353+
retry_count += 1
354+
raise e if retry_count > MAX_REQUEST_RETRIES
355+
356+
sleep(rand(3.0..10.0))
357+
retry
358+
end
359+
end
360+
407361
# Update return type to allow returning a Hash or nil
408362
sig do
409363
params(version_manager: T.nilable(Dependabot::Ecosystem::VersionManager))

0 commit comments

Comments
 (0)