来自StandardError的营救,将覆盖其他抢救块

问题描述 投票:0回答:2

我正在尝试创建一个处理我在include中的application_controller.rb的API错误的模块。这是我模块的self.included功能。

def self.included(clazz)
  clazz.class_eval do

    rescue_from ActiveRecord::RecordNotFound do |e|
      respond(:record_not_found, 404, e.message)
    end
    rescue_from ActiveRecord::RecordInvalid do |e|
      respond(:record_invalid, 422, e.record.errors.full_messages)
    end
    rescue_from ActionController::ParameterMissing do |e|
      respond(:bad_request, 400, e.message)
    end
    rescue_from StandardError do |e|
      respond(:standard_error, 500, e.message)
    end
  end
end

我遇到的问题是StandardError捕获了所有错误,包括我在其他rescue_from块中定义的其他错误。

我想代替这样的东西:

begin

rescue ActiveRecord::RecordNotFound => e

rescue ActiveRecord::RecordInvalid => e

rescue ActionController::ParameterMissing => e

rescue StandardError => e

end

感谢您的帮助。

ruby-on-rails ruby ruby-on-rails-6
2个回答
3
投票

我会将其重构为单个rescue_from,然后通过检查e.class进行深入研究:

rescue_from StandardError do |e|
  case e.class
  when ActiveRecord::RecordNotFound
    respond(:record_not_found, 404, e.message)
  when ActiveRecord::RecordInvalid
    respond(:record_invalid, 422, e.record.errors.full_messages)
  when ActionController::ParameterMissing
    respond(:record_not_found, 400, e.message)
  else
    respond(:standard_error, 500, e.message)
  end
end

0
投票

问题是rescue_from处理程序是>

处理程序是继承的。从右到左,从下到上,以及上层结构搜索它们。

这意味着这些块以相反的顺序执行,因此您的4个rescue_from看起来更像:

rescue_from

相反。最后添加的处理程序是执行的第一个处理程序,这一事实使诸如子控制器之类的东西可以覆盖父控制器中的处理程序。因此,要解决此问题,只需颠倒您定义begin rescue StandardError => e rescue ActionController::ParameterMissing => e rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordNotFound => e end 块的顺序,事情便会按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.