@@ -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
@@ -184,15 +156,7 @@ def record_update_job_unknown_error(error_type:, error_details:)
184156 "error-details" : error_details
185157 }
186158 }
187- response = http_client . post ( api_url , json : body )
188- raise ApiError , response . body if response . code >= 400
189- rescue HTTP ::ConnectionError , OpenSSL ::SSL ::SSLError
190- retry_count ||= 0
191- retry_count += 1
192- raise if retry_count > MAX_REQUEST_RETRIES
193-
194- sleep ( rand ( 3.0 ..10.0 ) )
195- retry
159+ send_http_request_with_retries ( :post , api_url , body )
196160 end
197161 end
198162
@@ -204,15 +168,7 @@ def mark_job_as_processed(base_commit_sha)
204168
205169 api_url = "#{ base_url } /update_jobs/#{ job_id } /mark_as_processed"
206170 body = { data : { "base-commit-sha" : base_commit_sha } }
207- response = http_client . patch ( api_url , json : body )
208- raise ApiError , response . body if response . code >= 400
209- rescue HTTP ::ConnectionError , OpenSSL ::SSL ::SSLError
210- retry_count ||= 0
211- retry_count += 1
212- raise if retry_count > MAX_REQUEST_RETRIES
213-
214- sleep ( rand ( 3.0 ..10.0 ) )
215- retry
171+ send_http_request_with_retries ( :patch , api_url , body )
216172 end
217173 end
218174
@@ -228,15 +184,7 @@ def update_dependency_list(dependencies, dependency_files)
228184 dependency_files : dependency_files
229185 }
230186 }
231- response = http_client . post ( api_url , json : body )
232- raise ApiError , response . body if response . code >= 400
233- rescue HTTP ::ConnectionError , OpenSSL ::SSL ::SSLError
234- retry_count ||= 0
235- retry_count += 1
236- raise if retry_count > MAX_REQUEST_RETRIES
237-
238- sleep ( rand ( 3.0 ..10.0 ) )
239- retry
187+ send_http_request_with_retries ( :post , api_url , body )
240188 end
241189 end
242190
@@ -249,15 +197,7 @@ def create_dependency_submission(dependency_submission)
249197 body = {
250198 data : dependency_submission
251199 }
252- response = http_client . post ( api_url , json : body )
253- raise ApiError , response . body if response . code >= 400
254- rescue HTTP ::ConnectionError , OpenSSL ::SSL ::SSLError
255- retry_count ||= 0
256- retry_count += 1
257- raise if retry_count > MAX_REQUEST_RETRIES
258-
259- sleep ( rand ( 3.0 ..10.0 ) )
260- retry
200+ send_http_request_with_retries ( :post , api_url , body )
261201 end
262202 end
263203
@@ -268,15 +208,7 @@ def record_ecosystem_versions(ecosystem_versions)
268208 body = {
269209 data : { ecosystem_versions : ecosystem_versions }
270210 }
271- response = http_client . post ( api_url , json : body )
272- raise ApiError , response . body if response . code >= 400
273- rescue HTTP ::ConnectionError , OpenSSL ::SSL ::SSLError
274- retry_count ||= 0
275- retry_count += 1
276- raise if retry_count > MAX_REQUEST_RETRIES
277-
278- sleep ( rand ( 3.0 ..10.0 ) )
279- retry
211+ send_http_request_with_retries ( :post , api_url , body )
280212 end
281213 end
282214
@@ -299,7 +231,7 @@ def increment_metric(metric, tags:)
299231 response = http_client . post ( api_url , json : body )
300232 # We treat metrics as fire-and-forget, so just warn if they fail.
301233 Dependabot . logger . debug ( "Unable to report metric '#{ metric } '." ) if response . code >= 400
302- rescue HTTP :: ConnectionError , OpenSSL :: SSL :: SSLError
234+ rescue * NETWORK_ERRORS_TO_RESCUE_FROM
303235 Dependabot . logger . debug ( "Unable to report metric '#{ metric } '." )
304236 end
305237 end
@@ -401,6 +333,28 @@ def record_cooldown_meta(job)
401333
402334 private
403335
336+ sig do
337+ params (
338+ request_type : T . any ( Symbol , String ) ,
339+ api_url : String ,
340+ json : T ::Hash [ T . untyped , T . untyped ]
341+ ) . void
342+ end
343+ def send_http_request_with_retries ( request_type , api_url , json )
344+ retry_count ||= 0
345+
346+ begin
347+ response = http_client . public_send ( request_type , api_url , json : json )
348+ raise ApiError , response . body if response . code >= 400
349+ rescue *NETWORK_ERRORS_TO_RESCUE_FROM => e
350+ retry_count += 1
351+ raise e if retry_count > MAX_REQUEST_RETRIES
352+
353+ sleep ( rand ( 3.0 ..10.0 ) )
354+ retry
355+ end
356+ end
357+
404358 # Update return type to allow returning a Hash or nil
405359 sig do
406360 params ( version_manager : T . nilable ( Dependabot ::Ecosystem ::VersionManager ) )
0 commit comments