rescue_fromなどを用いたエラーハンドリングをリファクタリング

【結論】

・例外をキャッチする方法として、begin~rescueメソッドがあるが、メソッド全体を指定する場合、beginは省略可能

・rescue_fromを利用すれば、指定したコントローラー全体の例外をキャッチする事が可能

【目次】

【本題】

エラーハンドリングのリファクタリング

404や500エラーが発生した際に、任意のエラーページを表示させるには、コントローラーで発生する例外をキャッチする必要があります。

例外をキャッチする一般的な方法として、begin~rescueを使用する方法があります。

class PostsController < ApplicationController
  def show
  begin
    @post = current_user.post.find(params[:id])
  rescue ActiveRecord::RecordNotFound => e
    render 'errors/error_404', status: :not_found
  end

  def edit
  begin
    @post = current_user.post.find(params[:id])
  rescue ActiveRecord::RecordNotFound => e
    render 'errors/error_404', status: :not_found
  end
end

但し、これだと何点か冗長な部分があるので、リファクタリングを行っていきます。

beginの省略

まず、例外を検知する範囲をメソッド全体に指定するのであれば、beginは省略可能です。

class PostsController < ApplicationController
  def show
    @post = current_user.post.find(params[:id])
  rescue ActiveRecord::RecordNotFound => e
    render 'errors/error_404', status: :not_found
  end

  def edit
    @post = current_user.post.find(params[:id])
  rescue ActiveRecord::RecordNotFound => e
    render 'errors/error_404', status: :not_found
  end
end

rescue_fromの活用

rescue ActiveRecord::RecordNotFound => eという記述がDRYでは無いので、共通化させます。 その際に利用するのが、rescue_fromです。

rescue_fromによって、コントローラー全体の例外をキャッチする事が可能になります。

class PostsController < ApplicationController
  rescue_from ActiveRecord::RecordNotFound do |exception|
    render 'errors/error_404', status: :not_found
  end

  def show
    @post = current_user.post.find(params[:id])
  end

  def edit
    @post = current_user.post.find(params[:id])
  end
end

これにより、各メソッドの見通しが非常に良くなりました。

最後に、今回のテーマと関係無いですが、@postを生成する部分もbefore_actionで共通化します。

class PostsController < ApplicationController
  rescue_from ActiveRecord::RecordNotFound do |exception|
    render 'errors/error_404', status: :not_found
  end

  before_action :set_post

  def show
  end

  def edit
  end

  private

  def set_post
    @post = current_user.posts.find(params[:id])
  end
end

これで完成です。

参考情報

https://ruby-rails.hatenadiary.com/entry/20141111/1415707101

[Ruby] 例外処理を実装する時のrescue書き方3パターン - Qiita

Rails tips: rescue_fromでコントローラのエラーをrescueする(翻訳)|TechRacho by BPS株式会社