Feature #21642
openIntroduce `IO::ConnectionResetError` and `IO::BrokenPipeError` as standardized IO-level exceptions.
Description
Currently, different IO implementations in Ruby raise inconsistent exception types when a connection is reset or broken.
For example:
# Plain TCP socket:
socket.read_nonblock(1024)
# => Errno::ECONNRESET
# SSL socket:
ssl_socket.read_nonblock(1024)
# => OpenSSL::SSL::SSLError: SSL_read: unexpected eof while reading
Both represent a connection reset by peer, but the errors differ significantly in type and message.
This inconsistency makes it difficult to handle connection-level errors generically across IO types.
Similarly, EPIPE
is used in some contexts to signal a broken connection, but again, the representation and message differ between IO classes.
Proposal¶
Introduce explicit subclasses of the corresponding system errors as part of Ruby’s standard IO interface:
class IO
class ConnectionResetError < Errno::ECONNRESET; end
class BrokenPipeError < Errno::EPIPE; end
end
Then, standardize the Ruby I/O ecosystem (including OpenSSL) to raise these subclasses instead of raw system errors or library-specific error wrappers.
This would establish a consistent, well-defined public interface for handling connection-level failures.
Motivation¶
-
Consistency: Users can handle
IO::ConnectionResetError
acrossIO
,TCPSocket
,OpenSSL::SSL::SSLSocket
, and other IO-like objects. -
Clarity: The name clearly expresses a high-level semantic (“connection reset”) rather than a low-level system error.
-
Extensibility: Other Ruby IO implementations (custom sockets, pipes, etc.) can follow the same convention.
-
Backwards Compatibility: Because
IO::ConnectionResetError < Errno::ECONNRESET
, existing rescue clauses continue to work:rescue Errno::ECONNRESET # still catches it end
Examples¶
begin
io.read_nonblock(1024)
rescue IO::ConnectionResetError
puts "Connection was reset by peer."
end
Impact on existing code¶
- Minimal to none.
- Existing code that rescues
Errno::ECONNRESET
orErrno::EPIPE
will continue to function. - Future code gains a more semantic and portable way to handle these common failure modes.