Forum: Ruby Exceptions inside loops...

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
darren kirby (Guest)
on 2006-06-03 00:44
(Received via mailing list)
Hello all, quite new to ruby here.

I am trying to figure out how to catch exceptions and I am not having
luck.
Basically I have a script that loops over an array of ports and tries to
connect to see if there is a service running. If there is nothing
running
then I get a "Connection refused" error (ECONNREFUSED). In this case I
just
want to print a small message and move on to the next port, however, my
attempt at this just terminates the loop entirely. Here's some
(simplified)
code:

begin telnetPorts.each do |port|
   puts "Port " + port.to_s + ":"
   t = TCPSocket.new(host,port)
   banner = t.gets
   t.close
end

rescue SystemCallError
   puts "Unable to connect to port: " + $!
end

As it stands, this does catch the exception just fine, but moves to the
next
block of code immediately. I tried using 'next' but it is giving me an
error:
"unexpected next". So how does one simply move on to the next port in
this
case? Do I need to rewrite it as a function?

Thanks for consideration,
-d
Mike F. (Guest)
on 2006-06-03 00:57
darren kirby wrote:
>> begin telnetPorts.each do |port|
>    puts "Port " + port.to_s + ":"
>    t = TCPSocket.new(host,port)
>    banner = t.gets
>    t.close
> end
>
> rescue SystemCallError
>    puts "Unable to connect to port: " + $!
> end

I believe you just need to move your exception handling inside the
each's block

telnetPorts.each do |port|
  begin
    puts "Port #{port}:"
    t = TCPSocket.new( host.port )
    puts t.gets
    t.close
  rescue SystemCallError
    puts "Unable to gonnect to port #{port}: #$!"
  end
end
darren kirby (Guest)
on 2006-06-03 01:06
(Received via mailing list)
quoth the Mike F.:
> >    puts "Unable to connect to port: " + $!
>     t.close
>   rescue SystemCallError
>     puts "Unable to gonnect to port #{port}: #$!"
>   end
> end

That did the trick, thank you.
Also thanks for for showing how to interpolate variables inside a
string.
I will get this with time...

Thanks again,
-d
Dave B. (Guest)
on 2006-06-03 13:15
(Received via mailing list)
darren kirby wrote:
> begin telnetPorts.each do |port|
>    puts "Port " + port.to_s + ":"
>    t = TCPSocket.new(host,port)
>    banner = t.gets
>    t.close
> end
>
> rescue SystemCallError
>    puts "Unable to connect to port: " + $!
> end

I see the question has been answered; let me just explain a little
further.

Here's the code you posted above with standard indentation:

begin
  telnetPorts.each do |port|
    puts "Port " + port.to_s + ":"
    t = TCPSocket.new(host,port)
    banner = t.gets
    t.close
  end
rescue SystemCallError
   puts "Unable to connect to port: " + $!
end

The first "end" closes the do..end block given to the each method. The
second end closes the begin..end block. The rescue clause applies to the
begin..end block.

(Obviously) begin..end is used to introduce a new scope, often for
exception handling like you're doing here, but you can see that if an
exception is caught, you end up outside the loop. If you added a "retry"
or "redo" to the rescue clause, you'd simply start the loop again from
the top.

You can add rescue clauses inside begin..end blocks and also def..end
method bodies:

def barf
  raise "some exception"
rescue RuntimeError
  puts "some exception was raised"
end

Now you can go back to your already-working solution from Mike
Fletcher's post.

Cheers,
Dave
darren kirby (Guest)
on 2006-06-03 20:38
(Received via mailing list)
quoth the Dave B.:
> > end
>     t.close
> exception handling like you're doing here, but you can see that if an
>   puts "some exception was raised"
> end
>
> Now you can go back to your already-working solution from Mike
> Fletcher's post.
>
> Cheers,
> Dave

Thanks for the additional enlightenment Dave, I did see that syntax in
some
sample code but I was getting "Unexpected KRescue or somesuch error.
However,
now it is working as it should, and I just need to find out how to send
Socket a timeout (SO_RCVTIMEO seems not to be defined) but that is
another
post!

Thanks guys,
-d
This topic is locked and can not be replied to.