1. terabyte

    Exceptionのtypo

    terabyte
Changes in body
Source | HTML | Preview
@@ -1,124 +1,124 @@
ちょっとこんがらがったので整理
### 先に結論
- アプリケーションレベルでの標準的なエラーは StandardError のサブクラス
- 型指定なしで rescue すると、StandardError のサブクラスのみ catch する
- なので、アプリケーション内で独自の例外を書く場合、普通は StandardError を使ったほうが良い
- 1.8 系の場合 Timeout::Error は、StandardError のサブクラスではない
### raise 関数に型を渡さない時に発生する例外は、RuntimeError
```rb
raise "エラーメッセージ" # => RuntimeError が発生
```
### StandardErrorって?
> 通常のプログラムで発生する可能性の高い 例外クラスを束ねるためのクラスです。
[class StandardError](http://docs.ruby-lang.org/ja/1.9.3/class/StandardError.html)
> Rubyの組み込み例外は(SystemExit や Interrupt のような脱出を目的としたものを除いて) StandardError のサブクラスです。
[制御構造](http://docs.ruby-lang.org/ja/1.9.3/doc/spec=2fcontrol.html)
### じゃあ、Exception の位置づけは?
>全ての例外の祖先のクラスです。
[class Exception](http://docs.ruby-lang.org/ja/1.9.3/class/Exception.html)
### StandardError は、Exception のサブクラス
Exceptionは、システム関係の例外も含む
アプリケーションレベルの例外であれば、StandardError を使うべきという思想らしい
そのため、rescue で、型指定をしない場合は、StandardError を継承している例外のみ catch する
```rb
begin
raise "エラーメッセージ" # catch する
raise Exception.new("エラーメッセージ") # catch しない
rescue => e
p e.message
end
```
-### Exceptopn を rescue するとどんな時困るの?
+### Exception を rescue するとどんな時困るの?
例えばこんな時
```rb
1.upto(10) do |i|
begin
p i
sleep(1)
rescue Exception => e
p e.class
p "catch!"
end
end
```
これを実行中に、ctrl-c で処理を停止しようとすると、Interrupt 例外が発生して、処理が続行されちゃう
けど、それって意図したことじゃないよね
```shell-session
$ ruby 01.rb
1
2
^CInterrupt
"catch!"
3
4
5
^CInterrupt
"catch!"
6
7
8
9
10
```
### 1.8 系での Timeout::Error の罠
1.8 系だとTimeout::Error が、StandardError ではなく、Interrupt を継承しているため、
型指定なしでの rescue では、catch されないという罠がある
[Class: Timeout::Error (Ruby 1.8.7)](http://www.ruby-doc.org/stdlib-1.8.7/libdoc/timeout/rdoc/Timeout/Error.html)
例えば、こんな時に、タイムアウトが発生しても catch されない
```rb
require 'net/http'
begin
Net::HTTP.start("test.net") do |http|
...
end
rescue =>e
...
end
```
例外の型指定は複数の型を指定できるので、こんな回避方法もある
```rb
begin
....
rescue Timeout::Error, StandardError =>e
end
```
ちなみに 1.9 系では、StandardError になっているので、解決している
[Class: Timeout::Error (Ruby 1.9.3)](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/timeout/rdoc/Timeout/Error.html)
そんな話
### 参考
- [Rubyで自前の例外クラスを作るときExceptionではなくStandardErrorを継承する理由 - yarbの日記]([
http://d.hatena.ne.jp/yarb/20121005/p1)
- [【Ruby】Ctrl-cの強制停止はrescueで補足できる | one's world](http://no-zom.jp/blog/?p=588)
- [Timeout::Errorに注意 - dreammindの日記](http://d.hatena.ne.jp/dreammind/20090217/1234813224)