在Ruby on Rails控制器中重构重复的救援异常处理程序

ugo*_*chi 2 ruby refactoring exception-handling ruby-on-rails

我在控制器中有两个操作方法,它们具有相同的重复代码,可以挽救两种不同类型的异常:

      def wave
        ...do something here...
      rescue ActionController::ParameterMissing => e
        render :json => {:error => e.message}, :status => 422
      rescue Vendor::ApiError => e
        render :json => {:error => e.message}, :status => 500
      end

      def run
        ...do something different here...
      rescue ActionController::ParameterMissing => e
        render :json => {:error => e.message}, :status => 422
      rescue Vendor::ApiError => e
        render :json => {:error => e.message}, :status => 500
      end
Run Code Online (Sandbox Code Playgroud)

能抢救处理程序只是被重构到一个共同的私有方法,并从两个叫runwave方法呢?

Vác*_*ner 6

你可以尝试这样的事情:

def wave
  error_handler do
    # ...do something here...
  end
end

def run
  error_handler do
    # ...do something different here...
  end
end

def error_handler
  yield
rescue ActionController::ParameterMissing => e
  render :json => {:error => e.message}, :status => 422
rescue Vendor::ApiError => e
  render :json => {:error => e.message}, :status => 500
end
Run Code Online (Sandbox Code Playgroud)

编辑:这只是从普通的 ruby​​ 角度来看,也许 Rails 已经有了更好的东西。


lde*_*eld 5

您可以在控制器中使用rescue_from来解除所有控制器操作中的错误.你会有这样的事情

class MyController < ApplicationController
  rescue_from ActionController::ParameterMissing do |exception|
    render :json => {:error => exception.message}, :status => 422
  end

  rescue_from Vendor::ApiError do |exception|
    render :json => {:error => exception.message}, :status => 500
  end

  def wave
    # ...
  end

  # ...
end
Run Code Online (Sandbox Code Playgroud)

如果您希望在所有控制器上执行此操作,您甚至可以将它放在应用程序控制器中(例如,可能有助于挽救ParameterMissing错误)