# Yet another question on exceptions

**URL:** <https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470>\
**Category:** Ruby\
**Created:** [February 10, 2006, 5:03pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470 "2006-02-10T17:03:37Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 5:03pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/1 "2006-02-10T17:03:37Z")

</div>

Hi,

If i use File::open to open/create a file objet, and if i use a block  
with it, the file will be automatically close when the block ends:

Now, considering this buggy snippet:

begin  
File.open(“my\_file”) do |fic|  
fic.puts(“bla”)  
end  
rescue Exception =\> e  
STDERR.puts(e)  
exit(1)  
end

Here, the “not opened for writing” exception will be raised, the block  
end will never be reached and the file will remain opened, isn’t it ?  
To circumvent this, i have to make fic a global variable and put the  
appropriate code in a ensure clause (or open a begin/ensure in the  
File.open block to close the file… too bad)

So, my question is: what’s the benefit of this idiom versus this one:

begin  
fd = File.new(“my\_file”)  
…  
rescue Exception =\> e  
STDERR.puts(e)  
exit(1)  
ensure  
fd.close if fd and not fd.closed?  
end

Is there something i’ve missed?

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 5:58pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/2 "2006-02-10T17:58:29Z")

</div>

Eric J. wrote:

> end
> 
> end
> 
> Is there something i’ve missed?

Yes, as Grennady pointed out. The benefit of using File#open with a  
block  
is exactly that you do not have to do the closing yourself. Less code,  
less errors.

Btw, your first example is overly complex. This does the same:

File.open(“my\_file”) do |fic|  
fic.puts(“bla”)  
end

17:53:40 [~]: ruby -e ‘File.open(“dsdsd”) {|io| p io}’ ; echo $?  
-e:1:in `initialize’: No such file or directory - dsdsd (Errno::ENOENT)  
from -e:1  
1  
17:53:55 [~]:

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 6:33pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/3 "2006-02-10T18:33:32Z")

</div>

“Robert K.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> Btw, your first example is overly complex. This does the same:
> 
> File.open(“my\_file”) do |fic|  
> fic.puts(“bla”)  
> end

Actually, i took the habit to always handle exceptions myself, hence  
the block begin/rescue…

Furthermore, it was a toy exemple: i like my scripts exit with  
different values for different problems.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 7:43pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/4 "2006-02-10T19:43:29Z")

</div>

David V. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> Well, File.open in the block version will reraise the exception precisely to  
> let you do that, it’s not supposed to silently ignore errors.

Ok, perhaps i’m not clear or perhaps i’ve missed something…

Suppose i want my script exit with different values depending on the  
error cases:

% ruby -e ‘File.open(“no.txt”) {|f| line = f.gets}’  
-e:1:in `initialize': No such file or directory - no.txt (Errno::ENOENT) from -e:1 % echo $? 1 % ruby -e 'File.open("yes.txt") {|f| f.puts("bla")}' -e:1:in `write’: not opened for writing (IOError)  
from -e:1  
from -e:1  
[titine]:~/Desktop % echo $?  
1

As it’s clearly not the same error, i don’t want the same return  
status. As i don’t know how to manage this gracefully with Ruby, i’m  
using a well-know idiom (at least for me…). That said, if there a  
more rubywaying solution, i buy it.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 8:04pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/5 "2006-02-10T20:04:03Z")

</div>

2006/2/10, Eric J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> % ruby -e ‘File.open(“no.txt”) {|f| line = f.gets}’
> 
> As it’s clearly not the same error, i don’t want the same return  
> status. As i don’t know how to manage this gracefully with Ruby, i’m  
> using a well-know idiom (at least for me…). That said, if there a  
> more rubywaying solution, i buy it.

Actually, catching those exceptions and exiting depending on them is  
perfectly ok. Although I would question the habit to always handle  
exceptions yourself. Often it’s not needed and one can end up handling  
exceptions too far down the call hierarchy. The nice thing about  
Ruby’s exceptions is that they are unchecked (borrowing this term from  
Java), which basically means that they are not declared. At times this  
can make it difficult to figure what exceptions can be thrown from a  
method but surprisingly often this is not an issue (at least not for  
me, maybe in larger software systems).

Kind regards

robert

PS: A variant you could do for multiple return values to avoid lots of  
similar rescue clauses:

RV = Hash.new(1).merge(  
Exception =\> 1,  
ERRNO::Foo =\> 2  
)

begin  
…  
rescue Exception =\> e  
STDERR.puts e  
exit RV[e.class]  
end

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 8:53pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/6 "2006-02-10T20:53:04Z")

</div>

DÅ?a Piatok 10 FebruÃ¡r 2006 19:43 Eric J. napÃ­sal:

> -e:1:in `initialize’: No such file or directory - no.txt (Errno::ENOENT)  
> As it’s clearly not the same error, i don’t want the same return  
> status. As i don’t know how to manage this gracefully with Ruby, i’m  
> using a well-know idiom (at least for me…). That said, if there a  
> more rubywaying solution, i buy it.

If you want to assign your own error codes, feel free to do so. As I  
said,  
that’s why File will reraise the exception. What I wanted to emphasise  
is  
that you don’t need to take care of cleanup of file handles while still  
being  
able to handle errors as you want to.

There’s nothing wrong with what you wrote in the original post, as long  
as you  
keep to printing the error message to standard error to keep with  
conventions.

---

<div class="post-metadata">

**Author:** ![cowboy\_x](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/d78d45/32.png) [@cowboy\_x](https://www.ruby-forum.com/u/cowboy_x)\
**Post date:** [February 10, 2006, 7:17pm UTC](https://www.ruby-forum.com/t/yet-another-question-on-exceptions/65470/7 "2006-02-10T19:17:43Z")

</div>

DÅ?a Piatok 10 FebruÃ¡r 2006 18:33 Eric J. napÃ­sal:

> Furthermore, it was a toy exemple: i like my scripts exit with  
> different values for different problems.

Well, File.open in the block version will reraise the exception  
precisely to  
let you do that, it’s not supposed to silently ignore errors.

Isn’t there a POSIX C header that defines various types of standard  
error  
codes for programs to return? In case I’m not imagining things, you  
might  
want to look into it and whether we can access those constants from Ruby  
to  
do things The Right Way.
