I am trying to create a module that handles API errors that I include
in my application_controller.rb
. Here is my module's self.included
function.
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
The problem I am having is that StandardError
catches all errors including the other errors I have defined in the other rescue_from
blocks.
I want to achieve something like this instead:
begin
rescue ActiveRecord::RecordNotFound => e
rescue ActiveRecord::RecordInvalid => e
rescue ActionController::ParameterMissing => e
rescue StandardError => e
end
Thanks for the help in advance.
I would refactor this into a single rescue_from
and then drill down by checking 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
The problem is that rescue_from
handlers are
Handlers are inherited. They are searched from right to left, from bottom to top, and up the hierarchy.
This means that the blocks are executed in reverse order so your 4 rescue_from
s look more like:
begin
rescue StandardError => e
rescue ActionController::ParameterMissing => e
rescue ActiveRecord::RecordInvalid => e
rescue ActiveRecord::RecordNotFound => e
end
instead. The fact that the last handler added is the first one executed allows things such as a child controller to override a handler in a parent controller. So, to fix, simply reverse the order you define your rescue_from
blocks and things should work as you intended.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.