diff --git a/lib/http/connection.rb b/lib/http/connection.rb index 9bdec865..938168bc 100644 --- a/lib/http/connection.rb +++ b/lib/http/connection.rb @@ -20,6 +20,7 @@ class Connection # @param [HTTP::Request] req # @param [HTTP::Options] options + # @raise [HTTP::ConnectionError] when failed to connect def initialize(req, options) @persistent = options.persistent? @keep_alive_timeout = options.keep_alive_timeout.to_f @@ -35,6 +36,8 @@ def initialize(req, options) send_proxy_connect_request(req) start_tls(req, options) reset_timer + rescue SocketError, SystemCallError => e + raise ConnectionError, "failed to connect: #{e}" end # @see (HTTP::Response::Parser#status_code) @@ -104,7 +107,7 @@ def read_headers! set_keep_alive rescue IOError, Errno::ECONNRESET, Errno::EPIPE => e - raise IOError, "problem making HTTP request: #{e}" + raise ConnectionError, "failed to read headers: #{e}" end # Callback for when we've reached the end of a response diff --git a/lib/http/errors.rb b/lib/http/errors.rb index 6fefd8ce..199fff1e 100644 --- a/lib/http/errors.rb +++ b/lib/http/errors.rb @@ -2,6 +2,9 @@ module HTTP # Generic error class Error < StandardError; end + # Generic Connection error + class ConnectionError < Error; end + # Generic Request error class RequestError < Error; end diff --git a/lib/http/response/status.rb b/lib/http/response/status.rb index 6de58f06..2916e1d2 100644 --- a/lib/http/response/status.rb +++ b/lib/http/response/status.rb @@ -108,6 +108,7 @@ def #{symbol}? # def bad_request? end def __setobj__(obj) + fail TypeError, "Expected #{obj.inspect} to respond to #to_i" unless obj.respond_to? :to_i @code = obj.to_i end diff --git a/spec/lib/http/request/writer_spec.rb b/spec/lib/http/request/writer_spec.rb index 66c766ed..a90de13b 100644 --- a/spec/lib/http/request/writer_spec.rb +++ b/spec/lib/http/request/writer_spec.rb @@ -37,7 +37,7 @@ let(:body) { 123 } it "raises an error" do - expect { writer }.to raise_error + expect { writer }.to raise_error(HTTP::RequestError) end end end @@ -59,12 +59,12 @@ context "when Transfer-Encoding not set" do let(:headers) { HTTP::Headers.new } - specify { expect { writer.stream }.to raise_error } + specify { expect { writer.stream }.to raise_error(HTTP::RequestError) } end context "when Transfer-Encoding is not chunked" do let(:headers) { HTTP::Headers.coerce "Transfer-Encoding" => "gzip" } - specify { expect { writer.stream }.to raise_error } + specify { expect { writer.stream }.to raise_error(HTTP::RequestError) } end end diff --git a/spec/lib/http/response/status_spec.rb b/spec/lib/http/response/status_spec.rb index a0931054..7e2051b2 100644 --- a/spec/lib/http/response/status_spec.rb +++ b/spec/lib/http/response/status_spec.rb @@ -1,7 +1,7 @@ RSpec.describe HTTP::Response::Status do describe ".new" do it "fails if given value does not respond to #to_i" do - expect { described_class.new double }.to raise_error + expect { described_class.new double }.to raise_error TypeError end it "accepts any object that responds to #to_i" do diff --git a/spec/lib/http_spec.rb b/spec/lib/http_spec.rb index 5272c7ab..258a8287 100644 --- a/spec/lib/http_spec.rb +++ b/spec/lib/http_spec.rb @@ -337,5 +337,10 @@ client = HTTP.headers("Cookie" => "foo=bar").cookies(:baz => :moo) expect(client.get(endpoint).to_s).to eq "foo: bar\nbaz: moo" end + + it "unifies socket errors into HTTP::ConnectionError" do + expect { HTTP.get "http://thishostshouldnotexists.com" }.to raise_error HTTP::ConnectionError + expect { HTTP.get "http://127.0.0.1:000" }.to raise_error HTTP::ConnectionError + end end end diff --git a/spec/support/connection_reuse_shared.rb b/spec/support/connection_reuse_shared.rb index b0986f5c..59633688 100644 --- a/spec/support/connection_reuse_shared.rb +++ b/spec/support/connection_reuse_shared.rb @@ -56,7 +56,7 @@ # rubocop:enable Style/RescueModifier # Should error because we tried to use a bad socket - expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error(IOError) + expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error HTTP::ConnectionError # Should succeed since we create a new socket second_socket = client.get("#{server.endpoint}/socket").body.to_s diff --git a/spec/support/http_handling_shared.rb b/spec/support/http_handling_shared.rb index b68b592d..3151d37c 100644 --- a/spec/support/http_handling_shared.rb +++ b/spec/support/http_handling_shared.rb @@ -173,7 +173,7 @@ # rubocop:enable Style/RescueModifier # Should error because we tried to use a bad socket - expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error(IOError) + expect { client.get("#{server.endpoint}/socket").body.to_s }.to raise_error HTTP::ConnectionError # Should succeed since we create a new socket second_socket_id = client.get("#{server.endpoint}/socket").body.to_s