質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 3

Ruby on Rails3はRubyによって書かれたオープンソースのウェブフレームワークです。Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

3回答

3372閲覧

Rubyの例外が多い件。あらゆる例外を捕捉してくれる便利機能は無いの?

komachi

総合スコア94

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 3

Ruby on Rails3はRubyによって書かれたオープンソースのウェブフレームワークです。Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

1クリップ

投稿2017/07/08 17:17

RailsでAPIを作ってます。通常のRailsアプリ同様、ユーザから送られてきたパラメータが正しいかどうかを検証するためバリデーションを実行しています。しかし、Railsにビルドインされている基本的なバリデーション以外に、独自にカスタムバリデーションを作っているのですが、ユーザから不正な値が送られてきた時に拾うべき例外が色々ありすぎてちゃんと例外を網羅できているのか、不安になります。

たとえば、ユーザから、year month dayの3つの整数がパラメータとして送られてきて、year/month/dayで表される日付が存在するかどうかを検証することを考えています。(2017/7/31は存在しうる日付なので許可し、一方2017/7/32は存在し得ない日付なのでエラーをあげる、という具合です。)

そこで、以下のような関数を考えました。

ruby

1 def valid_date 2 errors[:base] << '日付の値が不正です。' unless set_date 3 end 4 5 def set_date 6 begin 7 date = Time.zone.parse('%#04d-%#02d-%#02d 00:00:00' % [self.year, self.month, self.day]) 8 rescue ArgumentError 9 self.date = nil 10 end 11 end

ここでは、存在し得ない日付が入力されたときにArgumentErrorを捕捉するようにしてるんですが、はたしてコレで充分か?という疑問が常につきまとうのです。たとえば、self.yearが存在しなければ、また別のエラーが吐かれてArgumentErrorでは捕捉できないのではないか? と思うのです。

そのような疑念を払拭するにはどうすればよいのでしょうか。RubyやRailsの例外を全部覚える必要があるのでしょうか。

もし、あらゆる例外を捕捉してくれる便利な仕組みがあれば、それを使いたいのですが、そのような仕組みはあるのでしょうか。。。。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

そのような疑念を払拭するにはどうすればよいのでしょうか。

テストを書きましょう。

あらゆる例外を捕捉してくれる便利な仕組みがあれば、それを使いたいのですが

あらゆる例外を捕捉するのは超バッドプラクティスなので止めましょう。

捕捉するのはそのメソッドで対処する術のある例外のみとするのが原則です。
アプリケーション実行中のいかなる箇所でも想定できない例外が発生してしまったなら、それはもうアプリケーションを停止させるしかない、ということです。

アプリケーションがクラッシュした時にどのようにリカバリーするかは、また別のレイヤーの話になります。

投稿2017/07/08 18:11

koko_u

総合スコア936

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komachi

2017/07/09 00:39

エラーは想定すべきもの、ということですね。 どういうときにどの例外が上がるのか、完璧に把握できていないので、テスト書いて、「このパラメータセットのときは、この例外が上がるんだな」って感じでひとつひとつ潰していくことにします。
guest

0

質問のコードであれば、入力が不正であることさえわかれば良さそうなので

def set_date begin date = Time.zone.parse('%#04d-%#02d-%#02d 00:00:00' % [self.year, self.month, self.day]) rescue self.date = nil end end

と例外クラスを指定しないrescueでも十分です。例外クラスを指定しない場合、(ほぼ)全ての例外を捕捉します。そしてこれは

date = Time.zone.parse(略) rescue nil

こう書けます。

こういう記法がある事からもわかるように、例外クラスを指定しないrescueが一般的にバッドプラクティスだということはありません。まずいのは、どういう例外が(例外クラスが、ではなく)起きるのか把握しないまま、例外クラスを指定しないrescueで例外を握りつぶしてしまうことです。(後置rescueには少し癖があるので、その点で避けた方がよいというガイドラインもあります)

あるメソッドがどういう例外を送出するかは、リファレンスを確認すればよい、と言いたいのですが、リファレンスには全ての例外が書かれているとは限りません。あるメソッドが正常に動作しないとすればそれはどのような状況か、ということを把握することなので、結局は知識と経験と勘の世界です。「あるメソッドに異常な入力や状況を与えたとして想定通り例外を送出する」ことはテストで確認出来ますが、「異常な入力や状況とは何か」は人間が考えなければなりません。

--

なお、rescue節は複数書けます

begin ... rescue ArgumentError # ArgumentErrorの時の処理 rescue TypeError # TypeErrorの時の処理 rescue # どっちにも引っかからなかった時の処理 end

投稿2017/07/11 12:24

suzukis

総合スコア1449

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Ruby

1# encoding: utf-8 2 3begin 4 raise ArgumentError, "ハローワールド" 5rescue => e 6 e_class_name = e.class 7 8 word = 9 if e_class_name == ZeroDivisionError 10 "不正な計算です。" 11 elsif e_class_name == ArgumentError 12 e.message 13 else 14 "よく分からないエラーです。" 15 end 16 17 puts word 18end 19

参考
rubyの例外についてまとめてみた
Rubyの例外処理(begin - rescueとraise)をもう一度きちんと確認してみた。

エラーのクラスを見てwhenで処理を分岐させるという方法を考えました。

追記
whenではうまくいかなかったのでifで分岐させることにしました。

投稿2017/07/08 18:09

編集2017/07/08 18:23
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komachi

2017/07/09 00:36

ふむ、なるほどですね。 これでよくわからないエラーも捕捉できますね。 ただ、上の方がおっしゃっているように、想定しないエラーが出ることがそもそも良くないとのことなので、テストを書いて例外を洗うことにしました。 ご回答ありがとうございました。☺️
退会済みユーザー

退会済みユーザー

2017/07/09 08:04 編集

どういたしまして(*'ω'*)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問