# Catching exceptions

**URL:** <https://rubytalk.org/t/catching-exceptions/16367>\
**Category:** ruby-talk\
**Created:** [9 February 2005 19:15 UTC](https://rubytalk.org/t/catching-exceptions/16367 "2005-02-09T19:15:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark\_Probert](https://avatars.discourse-cdn.com/v4/letter/m/d2c977/32.png) [@Mark\_Probert](https://rubytalk.org/u/Mark_Probert)\
**Post date:** [9 February 2005 19:15 UTC](https://rubytalk.org/t/catching-exceptions/16367/1 "2005-02-09T19:15:42Z")

</div>

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)  
&nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
&nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
&nbsp;&nbsp;&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;s \<\< " made it!"  
&nbsp;&nbsp;&nbsp;&nbsp;rescue Errno::ETIMEDOUT  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
&nbsp;&nbsp;&nbsp;&nbsp;rescue Exception =\> e  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
&nbsp;&nbsp;&nbsp;&nbsp;ensure  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.close  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;return s  
end  
puts alive('10.10.10.2')

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

Regards,

-mark. (probertm at acm dot org)

---

<div class="post-metadata">

**Author:** ![Kent\_S2](https://avatars.discourse-cdn.com/v4/letter/k/c6cbf5/32.png) [@Kent\_S2](https://rubytalk.org/u/Kent_S2)\
**Post date:** [9 February 2005 19:31 UTC](https://rubytalk.org/t/catching-exceptions/16367/2 "2005-02-09T19:31:03Z")

</div>

Mark Probert \<probertm@acm.org\> 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)  
> &nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
> &nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
> &nbsp;&nbsp;&nbsp;&nbsp;begin  
> &nbsp;&nbsp;&nbsp;s \<\< " made it!"  
> &nbsp;&nbsp;&nbsp;&nbsp;rescue Errno::ETIMEDOUT  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
> &nbsp;&nbsp;&nbsp;&nbsp;rescue Exception =\> e  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
> &nbsp;&nbsp;&nbsp;&nbsp;ensure  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.close  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;return s  
> end  
> puts alive('10.10.10.2')
> 
> $ ruby test.rb  
> test.rb:6:in `initialize': Operation timed out - connect(2) (Errno::ETIMEDOUT)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from test.rb:6:in `new'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from test.rb:6:in `alive'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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)  
&nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
&nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " made it!"  
&nbsp;&nbsp;&nbsp;&nbsp;return s  
rescue Errno::ETIMEDOUT  
&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
rescue Exception =\> e  
&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
ensure  
&nbsp;&nbsp;&nbsp;&nbsp;t.close  
end

Cheers,  
Kent

---

<div class="post-metadata">

**Author:** ![Gennady1](https://avatars.discourse-cdn.com/v4/letter/g/a4c791/32.png) [@Gennady1](https://rubytalk.org/u/Gennady1)\
**Post date:** [9 February 2005 19:32 UTC](https://rubytalk.org/t/catching-exceptions/16367/3 "2005-02-09T19:32:11Z")

</div>

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)  
> > &nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
> > &nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
> > &nbsp;&nbsp;&nbsp;&nbsp;begin  
> > &nbsp;&nbsp;&nbsp;s \<\< " made it!"  
> > &nbsp;&nbsp;&nbsp;&nbsp;rescue Errno::ETIMEDOUT  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
> > &nbsp;&nbsp;&nbsp;&nbsp;rescue Exception =\> e  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
> > &nbsp;&nbsp;&nbsp;&nbsp;ensure  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.close  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;return s  
> > end  
> > puts alive('10.10.10.2')
> > 
> > $ ruby test.rb  
> > test.rb:6:in `initialize': Operation timed out - connect(2) (Errno::ETIMEDOUT)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from test.rb:6:in `new'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from test.rb:6:in `alive'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from test.rb:19
> > 
> > Regards,
> > 
> > -mark. (probertm at acm dot org)

---

<div class="post-metadata">

**Author:** ![Mark\_Probert](https://avatars.discourse-cdn.com/v4/letter/m/d2c977/32.png) [@Mark\_Probert](https://rubytalk.org/u/Mark_Probert)\
**Post date:** [9 February 2005 23:28 UTC](https://rubytalk.org/t/catching-exceptions/16367/4 "2005-02-09T23:28:05Z")

</div>

Hi ..

> Mark Probert \<probertm@acm.org\> 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:

&nbsp;&nbsp;require 'socket'  
&nbsp;&nbsp;def alive(host, port=80)  
&nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
&nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " made it!"  
&nbsp;&nbsp;&nbsp;&nbsp;t.close  
&nbsp;&nbsp;&nbsp;&nbsp;return s  
&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;&nbsp;&nbsp;rescue Errno::ETIMEDOUT  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
&nbsp;&nbsp;&nbsp;&nbsp;rescue Exception =\> e  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
&nbsp;&nbsp;end  
&nbsp;&nbsp;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

&nbsp;&nbsp;t = TCPSocket.new()  
&nbsp;&nbsp;begin  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\<stuff\>  
&nbsp;&nbsp;rescue \<errors\>  
&nbsp;&nbsp;ensure  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.close  
&nbsp;&nbsp;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?

> **···**
>
> On Wednesday 09 February 2005 11:31, Kent Sibilev wrote:
> 
> --  
> -mark. (probertm at acm dot org)

---

<div class="post-metadata">

**Author:** ![Mark\_Probert](https://avatars.discourse-cdn.com/v4/letter/m/d2c977/32.png) [@Mark\_Probert](https://rubytalk.org/u/Mark_Probert)\
**Post date:** [9 February 2005 23:35 UTC](https://rubytalk.org/t/catching-exceptions/16367/5 "2005-02-09T23:35:11Z")

</div>

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

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

Regards,

> **···**
>
> On Wednesday 09 February 2005 11:32, Gennady Bystritksy wrote:
> 
> --  
> -mark. (probertm at acm dot org)

---

<div class="post-metadata">

**Author:** ![Gennady1](https://avatars.discourse-cdn.com/v4/letter/g/a4c791/32.png) [@Gennady1](https://rubytalk.org/u/Gennady1)\
**Post date:** [10 February 2005 00:16 UTC](https://rubytalk.org/t/catching-exceptions/16367/6 "2005-02-10T00:16:03Z")

</div>

Mark Probert wrote:

> Yes. The close() in the ensure is then out of scope. Moving it into the begin .. block like
> 
> &nbsp;&nbsp;def alive(host, port=80)  
> &nbsp;&nbsp;&nbsp;&nbsp;s = "host=#{host} : "  
> &nbsp;&nbsp;&nbsp;&nbsp;begin  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t = TCPSocket.new(host, port)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " made it!"  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t.close

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^^^^^^^  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This will not be executed.

> &nbsp;&nbsp;&nbsp;&nbsp;rescue Errno::ETIMEDOUT  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " Timed out -- node unreachable"  
> &nbsp;&nbsp;&nbsp;&nbsp;rescue Exception =\> e  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s \<\< " exception = #{e}"  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;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.
