Ruby on rails 如何在Rails rescue_from语句中重新引发Ruby异常?

Ruby on rails 如何在Rails rescue_from语句中重新引发Ruby异常?,ruby-on-rails,pundit,rescue,rocketpants,Ruby On Rails,Pundit,Rescue,Rocketpants,我的Rails 4应用程序使用JSON API和Pundit进行授权 我在/app/controllers/api/v1/base_controller.rb文件中有代码来处理来自Pundit的错误。每当用户未被授权更新资源时,Pundit就会抛出一个NotAuthorizedError异常,我用user\u not\u authorized方法将其解救: class API::V1::BaseController < RocketPants::Base include Pundit

我的Rails 4应用程序使用JSON API和Pundit进行授权

我在
/app/controllers/api/v1/base_controller.rb
文件中有代码来处理来自Pundit的错误。每当用户未被授权更新资源时,Pundit就会抛出一个
NotAuthorizedError
异常,我用
user\u not\u authorized
方法将其解救:

class API::V1::BaseController < RocketPants::Base
  include Pundit
  version 1

  rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized

  def user_not_authorized
    error! :forbidden
  end

end
然而,调用
错误立即启动请求:

Completed 500 Internal Server Error in 143ms

RocketPants::Forbidden - RocketPants::Forbidden:
  rocket_pants (1.13.1) lib/rocket_pants/controller/error_handling.rb:44:in `error!'
  app/controllers/api/v1/base_controller.rb:61:in `user_not_authorized'
完整堆栈跟踪

为什么
错误没有出现方法执行从我的Pundit异常处理程序调用时应该执行的操作?

如果我输入
错误!:禁止的<代码>在我的控制器动作中间,它按预期工作。

对于上下文,从
base\u controller.rb继承并调用Pundit的
authorize
方法的控制器如下所示:

{
  "error":             "forbidden",
  "error_description": "The requested action was forbidden."
}
class API::V1::MealsController < API::V1::BaseController

  before_filter :find_entity

  def create
    meal = @entity.meals.build(meal_params)

    authorize(@entity, :update?)

    if meal.save
      expose meal, status: :created
    else
      expose meal.errors, status: 422
    end
  end

end
class API::V1::MealsController
显然,在
解救中引发异常是个坏主意,根据Rails文档,在处理程序中引发的异常不会冒泡:

异常处理程序中引发的异常不会向上传播

文件:

我没有重新引发RocketPants的异常,而是自己创建并返回JSON错误消息:

  def user_not_authorized
    # error! :forbidden
    head 403
    error = { error: 'Action not allowed.', error_description: 'Sorry, you are not allowed to perform this action.'}
    expose error
  end
这管用

更新

此后,我找到了一个更干净的解决方案:只需将权威例外映射到RocketPants例外。这意味着每当出现
Pundit::NotAuthorizedError
错误时,它将被视为
RocketPants::probled
错误

将整个解决方案简化为
base\u controller.rb顶部的一行代码:

  map_error! Pundit::NotAuthorizedError, RocketPants::Forbidden
不需要处理程序