QA@IT

Railsで例外時に適切なフォーマットでエラーのレスポンスを返したい

3664 PV

コントローラ内で例外が起きるとproduction環境では500.htmlまたは404.htmlが返されるはずですが、JSONやXMLリクエストの場合はこれをそれぞれのフォーマットで返すようにしたいです。そこで、

class ApplicationController < ActionController::Base
  rescue_from ActiveRecord::RecordNotFound, :with => :record_not_found

  private

  def record_not_found
    respond_to do |format|
      format.html { render :status => 404 }
      format.xml  { render :status => 404 }
      format.json { render :status => 404 }
    end
  end
end

rescue_fromで例外をハンドリングすることを思いつきましたが、これだと例外クラスを指定する必要があり煩雑です。デフォルトでフォーマットに沿ってレスポンスを返すようにするにはどうすればいいでしょうか?

回答

個人的によくやるのが、

module ExceptionHelper
  ServerError = [
    Errno::ECONNRESET,
    Errno::ETIMEDOUT,
    ...
  ]
  NotFound = [
    ActiveRecord::RecordNotFound,
    ...
  ]
end

lib/exception_helper.rbとして保存しておき、

class ApplicationController < ActionController::Base
  rescue_from *ExceptionHelper::ServerError, :with => lambda { render_500 }
  rescue_from *ExceptionHelper::NotFound, :with => lambda { render_404 }
end

みたいな感じで、通知が欲しくない例外を運用がはじまってから徐々に追加していくやり方です。

どうしても手抜きしたいなら、

rescue_from StandardError

あるいはもっと強力に

rescue_from Exception

とでもすれば、本当にあらゆる例外を拾いますけど、重大なエラーまで飲み込んでしまうのでおすすめできる方法じゃないです。

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。