Skip to content

Commit 7b5691c

Browse files
authored
Socket.tcp and TCPSocket.new raises IO::TiemoutError with user specified timeout (ruby#15602)
* `Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout In ruby#11880, `rsock_connect()` was changed to raise `IO::TimeoutError` when a user-specified timeout occurs. However, when `TCPSocket.new` attempts to connect to multiple destinations, it does not use `rsock_connect()`, and instead raises `Errno::ETIMEDOUT` on timeout. As a result, the exception class raised on timeout could differ depending on whether there were multiple destinations or not. To align this behavior with the implementation of `rsock_connect()`, this change makes `TCPSocket.new` raise `IO::TimeoutError` when a user-specified timeout occurs. Similarly, `Socket.tcp` is updated to raise `IO::TimeoutError` when a timeout occurs within the method. (Note that the existing behavior of `Addrinfo#connect_internal`, which Socket.tcp depends on internally and which raises `Errno::ETIMEDOUT` on timeout, is not changed.) * [ruby/net-http] Raise `Net::OpenTimeout` when `TCPSocket.open` raises `IO::TimeoutError`. With the changes in ruby#15602, `TCPSocket.open` now raises `IO::TimeoutError` when a user-specified timeout occurs. This change updates #connect to handle this case accordingly. ruby/net-http@f64109e1cf
1 parent 4c38419 commit 7b5691c

File tree

5 files changed

+11
-11
lines changed

5 files changed

+11
-11
lines changed

ext/socket/ipsocket.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ struct inetsock_arg
2929
void
3030
rsock_raise_user_specified_timeout(void)
3131
{
32-
VALUE errno_module = rb_const_get(rb_cObject, rb_intern("Errno"));
33-
VALUE etimedout_error = rb_const_get(errno_module, rb_intern("ETIMEDOUT"));
34-
rb_raise(etimedout_error, "user specified timeout");
32+
rb_raise(rb_eIOTimeoutError, "user specified timeout");
3533
}
3634

3735
static VALUE

ext/socket/lib/socket.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil,
905905
end
906906
end
907907

908-
raise(Errno::ETIMEDOUT, 'user specified timeout') if expired?(now, user_specified_open_timeout_at)
908+
raise(IO::TimeoutError, 'user specified timeout') if expired?(now, user_specified_open_timeout_at)
909909

910910
if resolution_store.empty_addrinfos?
911911
if connecting_sockets.empty? && resolution_store.resolved_all_families?
@@ -918,7 +918,7 @@ def self.tcp_with_fast_fallback(host, port, local_host = nil, local_port = nil,
918918

919919
if (expired?(now, user_specified_resolv_timeout_at) || resolution_store.resolved_all_families?) &&
920920
(expired?(now, user_specified_connect_timeout_at) || connecting_sockets.empty?)
921-
raise Errno::ETIMEDOUT, 'user specified timeout'
921+
raise IO::TimeoutError, 'user specified timeout'
922922
end
923923
end
924924
end

lib/net/http.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1676,7 +1676,9 @@ def connect
16761676
begin
16771677
s = timeouted_connect(conn_addr, conn_port)
16781678
rescue => e
1679-
e = Net::OpenTimeout.new(e) if e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
1679+
if (defined?(IO::TimeoutError) && e.is_a?(IO::TimeoutError)) || e.is_a?(Errno::ETIMEDOUT) # for compatibility with previous versions
1680+
e = Net::OpenTimeout.new(e)
1681+
end
16801682
raise e, "Failed to open TCP connection to " +
16811683
"#{conn_addr}:#{conn_port} (#{e.message})"
16821684
end

test/socket/test_socket.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ def test_tcp_socket_resolv_timeout
909909
910910
Addrinfo.define_singleton_method(:getaddrinfo) { |*_| sleep }
911911
912-
assert_raise(Errno::ETIMEDOUT) do
912+
assert_raise(IO::TimeoutError) do
913913
Socket.tcp("localhost", port, resolv_timeout: 0.01)
914914
end
915915
ensure
@@ -934,7 +934,7 @@ def test_tcp_socket_resolv_timeout_with_connection_failure
934934
935935
server.close
936936
937-
assert_raise(Errno::ETIMEDOUT) do
937+
assert_raise(IO::TimeoutError) do
938938
Socket.tcp("localhost", port, resolv_timeout: 0.01)
939939
end
940940
RUBY
@@ -951,7 +951,7 @@ def test_tcp_socket_open_timeout
951951
end
952952
end
953953
954-
assert_raise(Errno::ETIMEDOUT) do
954+
assert_raise(IO::TimeoutError) do
955955
Socket.tcp("localhost", 12345, open_timeout: 0.01)
956956
end
957957
RUBY

test/socket/test_tcp.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def test_tcp_initialize_open_timeout
8080
port = server.connect_address.ip_port
8181
server.close
8282

83-
assert_raise(Errno::ETIMEDOUT) do
83+
assert_raise(IO::TimeoutError) do
8484
TCPSocket.new(
8585
"localhost",
8686
port,
@@ -321,7 +321,7 @@ def test_initialize_resolv_timeout_with_connection_failure
321321
port = server.connect_address.ip_port
322322
server.close
323323

324-
assert_raise(Errno::ETIMEDOUT) do
324+
assert_raise(IO::TimeoutError) do
325325
TCPSocket.new(
326326
"localhost",
327327
port,

0 commit comments

Comments
 (0)