我正在尝试创建一个处理我在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
感谢您的帮助。
我会将其重构为单个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
问题是rescue_from
处理程序是>
处理程序是继承的。从右到左,从下到上,以及上层结构搜索它们。
这意味着这些块以相反的顺序执行,因此您的4个
rescue_from
看起来更像:
rescue_from
相反。最后添加的处理程序是执行的第一个处理程序,这一事实使诸如子控制器之类的东西可以覆盖父控制器中的处理程序。因此,要解决此问题,只需颠倒您定义
begin rescue StandardError => e rescue ActionController::ParameterMissing => e rescue ActiveRecord::RecordInvalid => e rescue ActiveRecord::RecordNotFound => e end
块的顺序,事情便会按预期工作。