@@ -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