例外処理って何。
例外処理とは
処理中に何らかのエラーが生じた際の処理を指している。
railsにおいては、create!やsave!が有名ですね。
それぞれエラーが生じたときの流れは下記の通りになります。
create!、save! → レコードの作成・保存に失敗 → 例外を発生させる
create、save → レコードの作成・保存に失敗 → nilを返す
(Railsで感嘆符!を理解しよう(save, save!) - Qiita)
例外処理の主なメソッドは以下の通り。
-
begin
-
rescue
-
retry
-
raise
-
ensure
-
begin, rescue
begin
methodの開始を指しています。
rescue
エラーが生じた場合の処理(例外処理)をrescueが指している。本来であれば、エラーが生じた際に処理が中断されてしまうが、resucueを記入すると、エラー時の処理を指定することができるので、エラーが起きてもその後の処理を続行することができる。
resucue無し
puts 10 / 0
puts "こんにちは"
//実行結果
divided by 0 (ZeroDivisionError)
途中で処理が中断されてしまうため、こんにちはが出力されない
resucue有り
begin
10 / 0
rescue
p "0で割れません"
end
puts "こんにちは"
//実行結果
0で割れません
こんにちは
最後まで処理を実行することができた。
hoge = nil
begin
hoge = hoge + 1
p "正常"
rescue
p "エラーですよ"
end
//hogeがnilのため、エラー(rescue以下の文字である、エラーですよ)が返ってくる。
仮に、下記のようにrescue = eとすると、eにエラー内容が格納されて、NoMethodErrorが返ってくる。
hoge = nil begin hoge = hoge + 1 p "正常" rescue => e p "エラーですよ" end
ポイント
エラーの対象となりそうな箇所をbeginで囲う。
エラーが発生した場合の処理をrescueの中に書く。
retry
エラーが生じた時点で、再度処理を実行し直してくれるメソッド
hoge = nil
begin
hoge = hoge + 1
p "正常"
rescue NoMethodError
puts "メソッドが存在しない"
hoge = 1 # hogeに値を設定したのでnilでは無くなる
retry #beginブロックを再度実行する
rescue => e
p "それ以外のエラー"
end
//実行結果
// メソッドが存在しない
// "正常"
// エラーが一度生じた時点でhogeに1が代入されている。
raise
任意で例外を発生させることのできるメソッド
hoge = nil
begin
p "処理開始前1"
raise NoMethodError
p "処理開始前2"
hoge = hoge + 1
p "正常"
rescue NoMethodError
puts "メソッドが存在しない"
rescue => e
p "それ以外のエラー"
end
出力結果
//"処理開始前1"
//メソッドが存在しない
上から順に実行されている。まず、処理開始前1が出力された後、raiseで意図的にNoMethodErrorを発生 NoMethodErrorが発生した場合の処理まで飛ぶ。つまり、「メソッドが存在しない」が出力される。
ensure
例外の有無に関係なく必ず実行される処理
hoge = nil
begin
p "処理開始前1"
raise NoMethodError
p "処理開始前2"
hoge = hoge + 1
p "正常"
rescue NoMethodError
puts "メソッドが存在しない"
rescue => e
p "それ以外のエラー"
ensure
p "必ず実行"
end
出力結果
//"処理開始前1"
//メソッドが存在しない
// 必ず実行
ActiveRecord::RecordNotFoundエラー
が発生した時に404ページをレンダーすることも多いそうです。また、例外処理をrescueするgemもあるみたいです。
404エラーをカスタマイズできるくらいの例外処理マスターになりたいものです。