[rubygems/rubygems] Split HTTP_ERRORS into retryable and non retryable

c241a640fc
This commit is contained in:
David Rodríguez 2025-06-17 21:58:04 +02:00 committed by Hiroshi SHIBATA
parent c4c646d1bb
commit 35dd2b2994
No known key found for this signature in database
GPG key ID: F9CF13417264FAC2
3 changed files with 41 additions and 35 deletions

View file

@ -72,7 +72,7 @@ module Bundler
end
end
HTTP_ERRORS = Downloader::HTTP_ERRORS
HTTP_ERRORS = (Downloader::HTTP_RETRYABLE_ERRORS + Downloader::HTTP_NON_RETRYABLE_ERRORS).freeze
deprecate_constant :HTTP_ERRORS
NET_ERRORS = [

View file

@ -3,13 +3,17 @@
module Bundler
class Fetcher
class Downloader
HTTP_ERRORS = [
Gem::Timeout::Error,
EOFError,
HTTP_NON_RETRYABLE_ERRORS = [
SocketError,
Errno::EADDRNOTAVAIL,
Errno::ENETDOWN,
Errno::ENETUNREACH,
Gem::Net::HTTP::Persistent::Error,
].freeze
HTTP_RETRYABLE_ERRORS = [
Gem::Timeout::Error,
EOFError,
Errno::ENETDOWN,
Errno::EINVAL,
Errno::ECONNRESET,
Errno::ETIMEDOUT,
@ -17,7 +21,6 @@ module Bundler
Gem::Net::HTTPBadResponse,
Gem::Net::HTTPHeaderSyntaxError,
Gem::Net::ProtocolError,
Gem::Net::HTTP::Persistent::Error,
Zlib::BufError,
Errno::EHOSTUNREACH,
].freeze
@ -86,19 +89,20 @@ module Bundler
connection.request(uri, req)
rescue OpenSSL::SSL::SSLError
raise CertificateFailureError.new(uri)
rescue *HTTP_ERRORS => e
rescue *HTTP_NON_RETRYABLE_ERRORS => e
Bundler.ui.trace e
if e.is_a?(SocketError) || e.is_a?(Errno::EADDRNOTAVAIL) || e.is_a?(Errno::ENETUNREACH) || e.is_a?(Gem::Net::HTTP::Persistent::Error)
host = uri.host
host_port = "#{host}:#{uri.port}"
host = host_port if filtered_uri.to_s.include?(host_port)
raise NetworkDownError, "Could not reach host #{host}. Check your network " \
"connection and try again."
else
rescue *HTTP_RETRYABLE_ERRORS => e
Bundler.ui.trace e
raise HTTPError, "Network error while fetching #{filtered_uri}" \
" (#{e})"
end
end
private

View file

@ -201,16 +201,17 @@ RSpec.describe Bundler::Fetcher::Downloader do
end
end
context "when the request response causes an error included in HTTP_ERRORS" do
context "when the request response causes an HTTP error" do
let(:message) { "error about network" }
let(:error_class) { RuntimeError }
let(:error) { error_class.new(message) }
before do
stub_const("#{described_class}::HTTP_ERRORS", [error_class])
allow(connection).to receive(:request).with(uri, net_http_get) { raise error }
end
context "that it's retryable" do
let(:error_class) { Gem::Timeout::Error }
it "should trace log the error" do
allow(Bundler).to receive_message_chain(:ui, :debug)
expect(Bundler).to receive_message_chain(:ui, :trace).with(error)
@ -233,6 +234,7 @@ RSpec.describe Bundler::Fetcher::Downloader do
"Network error while fetching http://username@www.uri-to-fetch.com/api/v2/endpoint (error about network)")
end
end
end
context "when error is about the host being down" do
let(:error_class) { Gem::Net::HTTP::Persistent::Error }