Catching exceptions

Discussion in 'Ruby' started by Mark Probert, Feb 9, 2005.

  1. Mark Probert

    Mark Probert Guest

    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)
    Mark Probert, Feb 9, 2005
    #1
    1. Advertising

  2. Mark Probert

    Kent Sibilev Guest

    Mark Probert <> writes:

    > 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
    Kent Sibilev, Feb 9, 2005
    #2
    1. Advertising

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

    Mark Probert wrote:
    > 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)
    >
    Gennady Bystritksy, Feb 9, 2005
    #3
  4. Mark Probert

    Mark Probert Guest

    Hi ..

    On Wednesday 09 February 2005 11:31, Kent Sibilev wrote:
    > Mark Probert <> writes:
    > > Can someone please let me know what I am doing wrong here?
    > > I can't seem to catch the exception ..
    > >

    >
    > 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?

    --
    -mark. (probertm at acm dot org)
    Mark Probert, Feb 9, 2005
    #4
  5. Mark Probert

    Mark Probert Guest

    Hi ..

    On Wednesday 09 February 2005 11:32, Gennady Bystritksy wrote:
    > 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,

    --
    -mark. (probertm at acm dot org)
    Mark Probert, Feb 9, 2005
    #5
  6. Mark Probert wrote:

    > 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.
    Gennady Bystritksy, Feb 10, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marina
    Replies:
    2
    Views:
    468
    Marina
    Jul 8, 2003
  2. Amil Hanish
    Replies:
    0
    Views:
    543
    Amil Hanish
    Apr 13, 2006
  3. Adam Maass
    Replies:
    5
    Views:
    396
    Sudsy
    Jul 22, 2003
  4. Mike Schilling
    Replies:
    2
    Views:
    346
    Mike Schilling
    Jul 16, 2003
  5. Mick
    Replies:
    0
    Views:
    421
Loading...

Share This Page