TCPsocket, Errno::ECONNREFUSED and ruby on Windows

While writing some code intended to run on both GNU/Linux and Windows¹ I ran
into a small problem regarding catching errors thrown from TCPsocket.open.
It would seem that, depending on the problem encountered by TCPsocket.open,
different errors get thrown. Failure to find the host results in an easy to
catch SocketError:

···

,----

irb(main):003:0> TCPsocket.open( “life.invalid”, 42 )
SocketError: getaddrinfo: Name or service not known
from (irb):3:in open' from (irb):3 ----

but, on my GNU/Linux box anyway, an attempt to connect to a valid host that
isn’t listening on the specified port results in Errno::ECONNREFUSED:

,----

irb(main):004:0> TCPsocket.open( “hagbard”, 42 )
Errno::ECONNREFUSED: Connection refused - “connect(2)”
from (irb):4:in open' from (irb):4 ----

So I end up with code a little like:

,----

begin
…do socket opening stuff…
rescue SocketError, Errno::ECONNREFUSED => e
print “Error connecting to server: #{e}\n”
end
`----

Which makes sense.

Except, that’s a problem over on Windows because, in the build of ruby I’ve
got over there, there is no Errno::ECONNREFUSED. There is, instead,
Errno::E10061 which, unsurprisingly, isn’t defined on GNU/Linux. Because of
this I’ve ended up with code that looks like:

,----

begin
…do socket opening stuff…
rescue SocketError, /WIN/i.match( RUBY_PLATFORM ) ? Errno::E10061 :
Errno::ECONNREFUSED => e
print “Error connecting to server: #{e}\n”
end
`----

which feels a little cumbersome to say the least.

Is this simply a problem with the Windows build that I’m using or is this a
common way of trying to do cross-platform stuff with ruby?

In both cases I’m using ruby 1.6.7. On GNU/Linux I built it from source and
on Windows I’m using the “Pragmatic Programmers” distribution.


¹ URL:http://www.davep.org/misc/dict.rb, yes, I know someone already did
something similar but I was writing this as a “get to know ruby” exercise.


Dave Pearson: | lbdb.el - LBDB interface.
http://www.davep.org/ | sawfish.el - Sawfish mode.
Emacs: | uptimes.el - Record emacs uptimes.
Emacs - davep | quickurl.el - Recall lists of URLs.

,----
> begin
> ...do socket opening stuff...
> rescue SocketError, Errno::ECONNREFUSED => e
> print "Error connecting to server: #{e}\n"
> end
`----

Why not

   begin
      # ...do socket opening stuff...
   rescue
      print "Error connecting to server: #{$!}\n"
   end

Guy Decoux

,----

begin
…do socket opening stuff…
rescue SocketError, Errno::ECONNREFUSED => e
print “Error connecting to server: #{e}\n”
end
`----

Why not

begin
# …do socket opening stuff…
rescue
print “Error connecting to server: #{$!}\n”
end

Because that catches all errors.

···


Dave Pearson
http://www.davep.org/