例外処理って何。

例外処理とは

処理中に何らかのエラーが生じた際の処理を指している。

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エラーをカスタマイズできるくらいの例外処理マスターになりたいものです。

 

【Rails】例外処理の書き方(begin, rescue, raise,retry, ensure) - Qiita

railsの例外処理の扱いについて