kbaba1001
2015/12/09 20:31:14 投稿
1

rescue_from?知らない子ですね

エラーハンドリングを rescue_from でやると辛いので gaffe rambulance を使います。

rescue_from の辛さ:

  • rescue_from で補足できない例外がある
  • RAILS_ENV ごとの処理の切り替えの手間
  • APIやAjaxのときだけエラー処理を変えたいようなケースが手間
  • 定義の順番で挙動が変わるのでわかりづらい
  • だいたい ApplicationController あたりが汚れる

Before

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  if Rails.env.production?
    rescue_from Exception, with: :handle_500
    rescue_from ActionController::RoutingError, with: :handle_404
  end

  rescue_from Unauthorized, with: :handle_401

  def handle_500(exception = nil)
    if request.xhr?
      render json: { error: '500' }, status: 500
    else
      render template: 'errors/500', status: 500
    end
  end

  def handle_404(exception = nil)
    if request.xhr?
      render json: { error: '404' }, status: 404
    else
      render template: 'errors/404', status: 404
    end
  end

  # 似たようなメソッドが続く...
end

After

# gaffe の README に従う

# Gemfile
gem 'gaffe'

# config/initializers/gaffe.rb
Gaffe.configure do |config|
  config.errors_controller = {
    %r[^/api/] => 'Api::ErrorsController',
    %r[^/] => 'ErrorsController'
  }
end

Gaffe.enable!

# app/controllers/errors_controller.rb
class ErrorsController < ApplicationController
  include Gaffe::Errors

  protect_from_forgery except: :show

  def show
    render "errors/#{@rescue_response}", status: @status_code
  end
end

# app/controllers/api/errors_controller.rb
class API::ErrorsController < API::ApplicationController
  include Gaffe::Errors

  protect_from_forgery except: :show
  layout false

  def show
    render json: {error: @exception.inspect}, status: @status_code
  end
end

みんなのコメント