mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
[rubygems/rubygems] Split HTTP_ERRORS into retryable and non retryable
c241a640fc
This commit is contained in:
parent
c4c646d1bb
commit
35dd2b2994
3 changed files with 41 additions and 35 deletions
|
@ -72,7 +72,7 @@ module Bundler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
HTTP_ERRORS = Downloader::HTTP_ERRORS
|
HTTP_ERRORS = (Downloader::HTTP_RETRYABLE_ERRORS + Downloader::HTTP_NON_RETRYABLE_ERRORS).freeze
|
||||||
deprecate_constant :HTTP_ERRORS
|
deprecate_constant :HTTP_ERRORS
|
||||||
|
|
||||||
NET_ERRORS = [
|
NET_ERRORS = [
|
||||||
|
|
|
@ -3,13 +3,17 @@
|
||||||
module Bundler
|
module Bundler
|
||||||
class Fetcher
|
class Fetcher
|
||||||
class Downloader
|
class Downloader
|
||||||
HTTP_ERRORS = [
|
HTTP_NON_RETRYABLE_ERRORS = [
|
||||||
Gem::Timeout::Error,
|
|
||||||
EOFError,
|
|
||||||
SocketError,
|
SocketError,
|
||||||
Errno::EADDRNOTAVAIL,
|
Errno::EADDRNOTAVAIL,
|
||||||
Errno::ENETDOWN,
|
|
||||||
Errno::ENETUNREACH,
|
Errno::ENETUNREACH,
|
||||||
|
Gem::Net::HTTP::Persistent::Error,
|
||||||
|
].freeze
|
||||||
|
|
||||||
|
HTTP_RETRYABLE_ERRORS = [
|
||||||
|
Gem::Timeout::Error,
|
||||||
|
EOFError,
|
||||||
|
Errno::ENETDOWN,
|
||||||
Errno::EINVAL,
|
Errno::EINVAL,
|
||||||
Errno::ECONNRESET,
|
Errno::ECONNRESET,
|
||||||
Errno::ETIMEDOUT,
|
Errno::ETIMEDOUT,
|
||||||
|
@ -17,7 +21,6 @@ module Bundler
|
||||||
Gem::Net::HTTPBadResponse,
|
Gem::Net::HTTPBadResponse,
|
||||||
Gem::Net::HTTPHeaderSyntaxError,
|
Gem::Net::HTTPHeaderSyntaxError,
|
||||||
Gem::Net::ProtocolError,
|
Gem::Net::ProtocolError,
|
||||||
Gem::Net::HTTP::Persistent::Error,
|
|
||||||
Zlib::BufError,
|
Zlib::BufError,
|
||||||
Errno::EHOSTUNREACH,
|
Errno::EHOSTUNREACH,
|
||||||
].freeze
|
].freeze
|
||||||
|
@ -86,18 +89,19 @@ module Bundler
|
||||||
connection.request(uri, req)
|
connection.request(uri, req)
|
||||||
rescue OpenSSL::SSL::SSLError
|
rescue OpenSSL::SSL::SSLError
|
||||||
raise CertificateFailureError.new(uri)
|
raise CertificateFailureError.new(uri)
|
||||||
rescue *HTTP_ERRORS => e
|
rescue *HTTP_NON_RETRYABLE_ERRORS => e
|
||||||
Bundler.ui.trace 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 = uri.host
|
||||||
host_port = "#{host}:#{uri.port}"
|
host_port = "#{host}:#{uri.port}"
|
||||||
host = host_port if filtered_uri.to_s.include?(host_port)
|
host = host_port if filtered_uri.to_s.include?(host_port)
|
||||||
raise NetworkDownError, "Could not reach host #{host}. Check your network " \
|
raise NetworkDownError, "Could not reach host #{host}. Check your network " \
|
||||||
"connection and try again."
|
"connection and try again."
|
||||||
else
|
rescue *HTTP_RETRYABLE_ERRORS => e
|
||||||
raise HTTPError, "Network error while fetching #{filtered_uri}" \
|
Bundler.ui.trace e
|
||||||
|
|
||||||
|
raise HTTPError, "Network error while fetching #{filtered_uri}" \
|
||||||
" (#{e})"
|
" (#{e})"
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -201,36 +201,38 @@ RSpec.describe Bundler::Fetcher::Downloader do
|
||||||
end
|
end
|
||||||
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(:message) { "error about network" }
|
||||||
let(:error_class) { RuntimeError }
|
|
||||||
let(:error) { error_class.new(message) }
|
let(:error) { error_class.new(message) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
stub_const("#{described_class}::HTTP_ERRORS", [error_class])
|
|
||||||
allow(connection).to receive(:request).with(uri, net_http_get) { raise error }
|
allow(connection).to receive(:request).with(uri, net_http_get) { raise error }
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should trace log the error" do
|
context "that it's retryable" do
|
||||||
allow(Bundler).to receive_message_chain(:ui, :debug)
|
let(:error_class) { Gem::Timeout::Error }
|
||||||
expect(Bundler).to receive_message_chain(:ui, :trace).with(error)
|
|
||||||
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should raise a Bundler::HTTPError" do
|
it "should trace log the error" do
|
||||||
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError,
|
allow(Bundler).to receive_message_chain(:ui, :debug)
|
||||||
"Network error while fetching http://www.uri-to-fetch.com/api/v2/endpoint (error about network)")
|
expect(Bundler).to receive_message_chain(:ui, :trace).with(error)
|
||||||
end
|
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError)
|
||||||
|
|
||||||
context "when there are credentials provided in the request" do
|
|
||||||
let(:uri) { Gem::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
|
|
||||||
before do
|
|
||||||
allow(net_http_get).to receive(:basic_auth).with("username", "password")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should raise a Bundler::HTTPError that doesn't contain the password" do
|
it "should raise a Bundler::HTTPError" do
|
||||||
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError,
|
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError,
|
||||||
"Network error while fetching http://username@www.uri-to-fetch.com/api/v2/endpoint (error about network)")
|
"Network error while fetching http://www.uri-to-fetch.com/api/v2/endpoint (error about network)")
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when there are credentials provided in the request" do
|
||||||
|
let(:uri) { Gem::URI("http://username:password@www.uri-to-fetch.com/api/v2/endpoint") }
|
||||||
|
before do
|
||||||
|
allow(net_http_get).to receive(:basic_auth).with("username", "password")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise a Bundler::HTTPError that doesn't contain the password" do
|
||||||
|
expect { subject.request(uri, options) }.to raise_error(Bundler::HTTPError,
|
||||||
|
"Network error while fetching http://username@www.uri-to-fetch.com/api/v2/endpoint (error about network)")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue