Issue #21642 has been updated by mame (Yusuke Endoh). ioquatix (Samuel Williams) wrote in #note-4:
- "Connection Reset" occurs during read, and indicates that the remote end has dropped the connection, and it's likely that we are missing data (as opposed to reaching end of stream).
I see, so it's still possible to "write" as well as "close".
So there are subtle differences. Modules like `IO::BrokenPipe` and `IO::ConnectionReset` might be suitable, but maybe they are too specific?
Both `BrokenPipe` and `ConnectionReset` only convey the nuance of "no further I/O possible" to me, so I couldn't understand the difference. While not user-action-based names, something like `IO::ReadError` and `IO::WriteError` would be clearer to me, though I'm unsure if they're appropriate. As I recall, @akr proposed and introduced `IO::WaitReadable`. I would like to hear his opinion.
Regarding OpenSSL, there are many places in OpenSSL that raise `SSLError`, so I think what you are suggesting is this:
```ruby class SSLReadError < SSLError include IO::ConnectionReset end ```
Is it sufficiently compatible?
Looks good to me. ---------------------------------------- Feature #21642: Introduce `IO::ConnectionResetError` and `IO::BrokenPipeError` as standardized IO-level exceptions. https://bugs.ruby-lang.org/issues/21642#change-114873 * Author: ioquatix (Samuel Williams) * Status: Open ---------------------------------------- Currently, different IO implementations in Ruby raise inconsistent exception types when a connection is reset or broken. For example: ```ruby # 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: ```ruby 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` across `IO`, `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: ```ruby rescue Errno::ECONNRESET # still catches it end ``` ### Examples ```ruby 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` or `Errno::EPIPE` will continue to function. * Future code gains a more semantic and portable way to handle these common failure modes. -- https://bugs.ruby-lang.org/