From 7b5691c3b000c763faa282e1f73db96afa2ecae1 Mon Sep 17 00:00:00 2001 From: Misaki Shioi <31817032+shioimm@users.noreply.github.com> Date: Wed, 17 Dec 2025 15:02:26 +0900 Subject: `Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout (#15602) * `Socket.tcp` and `TCPSocket.new` raises `IO::TiemoutError` with user specified timeout In https://github.com/ruby/ruby/pull/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 https://github.com/ruby/ruby/pull/15602, `TCPSocket.open` now raises `IO::TimeoutError` when a user-specified timeout occurs. This change updates #connect to handle this case accordingly. https://github.com/ruby/net-http/commit/f64109e1cf --- ext/socket/ipsocket.c | 4 +--- ext/socket/lib/socket.rb | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'ext') diff --git a/ext/socket/ipsocket.c b/ext/socket/ipsocket.c index ba1b81b3ad..20d9101c11 100644 --- a/ext/socket/ipsocket.c +++ b/ext/socket/ipsocket.c @@ -29,9 +29,7 @@ struct inetsock_arg void rsock_raise_user_specified_timeout(void) { - VALUE errno_module = rb_const_get(rb_cObject, rb_intern("Errno")); - VALUE etimedout_error = rb_const_get(errno_module, rb_intern("ETIMEDOUT")); - rb_raise(etimedout_error, "user specified timeout"); + rb_raise(rb_eIOTimeoutError, "user specified timeout"); } static VALUE diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index 49fb3fcc6d..6d04ca2483 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -905,7 +905,7 @@ class Socket < BasicSocket end end - raise(Errno::ETIMEDOUT, 'user specified timeout') if expired?(now, user_specified_open_timeout_at) + raise(IO::TimeoutError, 'user specified timeout') if expired?(now, user_specified_open_timeout_at) if resolution_store.empty_addrinfos? if connecting_sockets.empty? && resolution_store.resolved_all_families? @@ -918,7 +918,7 @@ class Socket < BasicSocket if (expired?(now, user_specified_resolv_timeout_at) || resolution_store.resolved_all_families?) && (expired?(now, user_specified_connect_timeout_at) || connecting_sockets.empty?) - raise Errno::ETIMEDOUT, 'user specified timeout' + raise IO::TimeoutError, 'user specified timeout' end end end -- cgit v1.2.3