首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rails rescue_from语句中重新引发rescue_from?

如何在Rails rescue_from语句中重新引发rescue_from?
EN

Stack Overflow用户
提问于 2016-05-18 03:22:43
回答 1查看 1.9K关注 0票数 1

我的Rails 4应用程序使用RocketPants作为它的JSON,并使用专家进行授权。

我在我的/app/controllers/api/v1/base_controller.rb文件中有处理来自专家的错误的代码。每当用户未被授权更新资源时,专家将抛出一个NotAuthorizedError异常,并使用我的user_not_authorized方法拯救它:

代码语言:javascript
复制
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

当我从异常处理程序调用error!方法RocketPants提供时,我希望得到如下所示的JSON响应:

代码语言:javascript
复制
{
  "error":             "forbidden",
  "error_description": "The requested action was forbidden."
}

但是,调用error!会立即破坏请求:

代码语言:javascript
复制
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'

全堆栈跟踪这里

为什么error! 方法没有执行从我的专家异常处理程序调用时应该做的事情?

如果我将error! :forbidden放在控制器操作的中间,它就会像预期的那样工作。

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

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-18 14:02:15

显然,在rescue_from中引发异常是个坏主意,而且根据Rails文档,在处理程序中引发的异常不会出现:

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

博士:http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html

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

代码语言:javascript
复制
  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::Forbidden错误。

将整个解决方案简化为base_controller.rb顶部的一行代码

代码语言:javascript
复制
  map_error! Pundit::NotAuthorizedError, RocketPants::Forbidden

不需要处理程序。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37289704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档