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

目次

お久しぶりです!
サーバエンジニアの井出です!

メインはPHPですが
最近railsに触れる機会多くなったので
今日はrailsの例外処理について
まとめようと思います。

例外処理とは

処理中に何かしらの理由でエラー発生した際の処理になります。

どんなシステムでもエラーは起きるもので
発生した際にどのような処理を行うかによって
調査などもしやすくなるものです。

railsの例外処理に使用するのは主に以下になります。

  • begin
  • rescue
  • retry
  • raise
  • ensure

begin、rescueについて

基本的な使用方法は以下のように
beginで始まり、rescueでエラー発生した時の処理を記載します。

これを実行すると以下の結果になります。

が出力されました。

hogeはnilなのでメモリに確保されていない変数になるため
加算したところエラーとなり、rescueの処理が走りました。

エラーの中身を詳しく知りたい場合は
rescue => eとすると、エラー内容がeに入ります。

これを実行すると以下の結果になります。

エラーの内容分かりやすくていいですね!

さらにエラーごとにrescueの例外処理を指定できるので
上記のエラーの場合に対しては、以下のような記載も可能になります。

先ほどのエラーを見ると「NoMethodError」をいう内容になっていました。
その場合のエラー処理を書く場合は、rescue NoMethodErrorとすると
記載可能となります。

retryについて

次はretryの説明になります。
名前からして察しが付くかもしれませんが
例外発生時に再度処理を行うための機能になります。

では実際にソースをみて行きましょう。

先ほどの、処理をそのまま使用する形で
rescue内に加え、retry処理を実行しました。

これを実行すると以下の結果になります。

実行結果の通り一度例外処理に入りましたが
hogeに値を設定し、nilではない状態にしretryで再度beginの処理を実行し
無事、正常処理になりました。

このように一度はエラーになったが何かしらの手を加えて
再度実行させるときなどに便利です。
以前使用した時は、ページアクセス時にpvを計測する処理で
ページ初期アクセス時はレコードが存在しないのでinsert、
2回目以降は存在しているのでupdateを実現したく
同時アクセス時はinsertが同時2回走りprimaryエラーとなるため
こちらのretry処理を駆使して実現させました。
同時アクセス時はどちらかが重複エラーとなるため
retryすることにより、レコードが存在している状態になるため
updateが走り、無事実現ができました。

raiseについて

raiseは任意で例外処理を発生させることができます。
必須項目不足などのバリエーションのエラー時などに
メインで使うかと思いますが、こちらもソースで確認してみましょう。

raise NoMethodErrorを指定することにより
NoMethodErrorの例外処理を発生させ
rescue NoMethodErrorの処理が走ります

これを実行すると以下の結果になります。

ensureについて

例外の有無に関係なく必ず実行される処理になります。
使用用途としては、あまりないかもですがDBのテーブルロックをする処理があり解除が必要、
ファイルオープンしていてクローズの処理が必要などになります・

記述方法としては以下になります。

これを実行すると以下の結果になります。

実行されましたね!

railsは勉強すればするほど
便利なものが多く凄くやりがいがある言語です!

セイコロンや()が無くても動作するなど
特殊な記法になれない部分もありますが
それも含めて味があるなと最近思うようになってきたので
日々勉強して、色々学んでいこうと思います!

また何か見つけたらここにまとめようと思います!

ご覧いただきありがとうございました!