Issue #9247 has been updated by mrkn (Kenta Murata). Description updated I think the following code can reproduce the full cases: # https://gist.github.com/mrkn/7945798 require 'socket' # Addrinfo#connect_internal puts "(1) Addrinfo#connect (connect_internal)" begin raise rescue p Addrinfo.tcp('www.ruby-lang.org', 80).connect end # Addrinfo.bind puts "\n(2) Addrinfo#bind" begin ai = Addrinfo.tcp(nil, 11229) raise rescue begin p ai.bind end end # Addrinfo.listen puts "\n(3) Addrinfo#listen" begin ai = Addrinfo.tcp(nil, 11228) raise rescue begin p ai.listen end end # Socket.ip_sockets_port0 puts "\n(4) Socket.tcp_server_sockets (ip_sockets_port0)" begin raise rescue begin Socket.tcp_server_sockets(0) rescue IOError $stderr.puts "#{$!.class}: #{$!}", $!.backtrace end end ---------------------------------------- Bug #9247: Bugs in socket.rb (exception retrieval) https://bugs.ruby-lang.org/issues/9247#change-43645 Author: ko1 (Koichi Sasada) Status: Open Priority: Normal Assignee: akr (Akira Tanaka) Category: lib Target version: current: 2.1.0 ruby -v: ruby 2.1.0dev (2013-12-13 trunk 44170) [i386-mswin32_110] Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN Ruby 2.1 (trunk) 2.0 and 1.9.3 both has a bug to retrieve exception. In the following code, opened socket is always closed. require 'socket' ai = Addrinfo.tcp(nil, 12345) begin raise rescue p ai.listen #=> #<Socket:(closed)> end This is because in socket.rb, there are such error handling code: # creates a listening socket bound to self. def listen(backlog=Socket::SOMAXCONN) sock = Socket.new(self.pfamily, self.socktype, self.protocol) begin sock.ipv6only! if self.ipv6? sock.setsockopt(:SOCKET, :REUSEADDR, 1) sock.bind(self) sock.listen(backlog) if block_given? yield sock else sock end ensure ### THIS LINE CLOSE `sock' every time when $! is not nil sock.close if !sock.closed? && (block_given? || $!) end end There are similar code in socket.rb. akr-san already knows this issue. This ticket is to note issues. We realize this issue because webrick use this feature from 2.1. The following code no longer works on 2.1. begin require 'xyzzy' # something like webrick rescue LoadError require 'webrick' server = WEBrick::HTTPServer.new(Port: 12345) end Because $! is an instance of LoadError. -- http://bugs.ruby-lang.org/