Catching exceptions

M

Mark Probert

Can someone please let me know what I am doing wrong here?
I can't seem to catch the exception ..


$ cat test.rb
require 'socket'

def alive(host, port=80)
s = "host=#{host} : "
t = TCPSocket.new(host, port)
begin
s << " made it!"
rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
ensure
t.close
end
return s
end
puts alive('10.10.10.2')

$ ruby test.rb
test.rb:6:in `initialize': Operation timed out - connect(2) (Errno::ETIMEDOUT)
from test.rb:6:in `new'
from test.rb:6:in `alive'
from test.rb:19

Regards,

-mark. (probertm at acm dot org)
 
K

Kent Sibilev

Mark Probert said:
Can someone please let me know what I am doing wrong here?
I can't seem to catch the exception ..


$ cat test.rb
require 'socket'

def alive(host, port=80)
s = "host=#{host} : "
t = TCPSocket.new(host, port)
begin
s << " made it!"
rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
ensure
t.close
end
return s
end
puts alive('10.10.10.2')

$ ruby test.rb
test.rb:6:in `initialize': Operation timed out - connect(2) (Errno::ETIMEDOUT)
from test.rb:6:in `new'
from test.rb:6:in `alive'
from test.rb:19

Regards,

-mark. (probertm at acm dot org)

Exception is being thrown from the outside of begin...end construct. Try this:

def alive(host, port=80)
s = "host=#{host} : "
t = TCPSocket.new(host, port)
s << " made it!"
return s
rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
ensure
t.close
end

Cheers,
Kent
 
G

Gennady Bystritksy

Have you tried to move your TCPSocket.new clause inside begin/rescue/end
block?
 
M

Mark Probert

Hi ..

Exception is being thrown from the outside of begin...end construct. Try
this:
Many thanks. The t.close() in the ensure is out of scope, so that the final
result looks like:

require 'socket'
def alive(host, port=80)
s = "host=#{host} : "
t = TCPSocket.new(host, port)
s << " made it!"
t.close
return s

rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
end
puts alive('10.10.10.2')

So, the next question I have is how does this actually work? Is there some
kind of implicit block around the code? If so, why does the explicit
begin .. end construct not work? How can I use an ensure for this?

Also, whilst I am at it ;-), I used the first formulation

t = TCPSocket.new()
begin
<stuff>
rescue <errors>
ensure
t.close
end

because t is not in scope if the creator is inside the begin .. end block. I
recall that this is the subject of much debate. How has it been resolved?
 
M

Mark Probert

Hi ..

Have you tried to move your TCPSocket.new clause inside begin/rescue/end
block?

Yes. The close() in the ensure is then out of scope. Moving it into the
begin .. block like

def alive(host, port=80)
s = "host=#{host} : "
begin
t = TCPSocket.new(host, port)
s << " made it!"
return s
t.close
rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
end
end

Regards,
 
G

Gennady Bystritksy

Mark said:
Yes. The close() in the ensure is then out of scope. Moving it into the
begin .. block like

def alive(host, port=80)
s = "host=#{host} : "
begin
t = TCPSocket.new(host, port)
s << " made it!"
return s
t.close
^^^^^^^
This will not be executed.
rescue Errno::ETIMEDOUT
s << " Timed out -- node unreachable"
rescue Exception => e
s << " exception = #{e}"
end
end

begin/rescue/ensure/end are all in the same (enclosing) scope. A
variable used in 'begin' block is available also in 'rescue' and
'ensure' blocks as well.

However, in your particular example, as an exception is raised in 'new',
't' will not reffer to any TCPSocket instance anyways, so doing t.close
does not make much sense (it will give you runtime error, as 't' will be
nil in this case).

Gennady.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top