如何从Ruby on Rails应用程序返回正确的HTTP错误代码

时间:2012-02-03 14:29:05

标签: ruby-on-rails ruby http

我有RoR 3.0网络应用程序,它充当OAuth API提供程序。现在,在API中我想向API使用者返回正确的HTTP错误代码。我该怎么做?

以下是示例:

def destroy_oauth
    @item = Item.find(params[:id])
    if(!@item.nil? && @item.user_id == current_user.id)
        @item.destroy
        respond_to do |format|
                format.js
                format.xml
        end
    else
        raise ActionController::RoutingError.new('Forbidden')
    end
end

因此,如果出现错误,我正在尝试返回Forbidden 403代码。仍然,当运行这个时,我总是得到404 Not Found返回。如何返回正确的代码?

或者这是某种网络服务器可配置的东西吗?

5 个答案:

答案 0 :(得分:51)

如果您只是提供状态代码并且没有正文,那么便捷的方式是

head 403

此方法还接受状态代码的符号名称,例如

head :forbidden

答案 1 :(得分:42)

您应该以正确的状态呈现页面。

render(:file => File.join(Rails.root, 'public/403.html'), :status => 403, :layout => false)

答案 2 :(得分:11)

根据ActionController::Head docs,只需在行动中使用此模式

  return head([status]) if/unless [some condition here]

示例:

  return head(:gone) if @record.deleted?
  return head(:forbidden) unless @user.owns?(@record)

return用于确保不会运行操作中的剩余代码。

答案 3 :(得分:1)

好吧,你可以用

:status =>500

但是,在默认情况下,Rails会处理错误类型呈现本身。

错误默认页面位于公共目录中。 500.html,404.html等..

For more information on :status , how to use it click here

答案 4 :(得分:1)

我认为你在这里有两个问题:首先是你的@item = Item.find(params[:id])行提高了404,执行永远不会到达预期的地方(if语句)。其次是你提出异常并且永远不会抓住它们。试试:

def destroy_oauth
   begin
     @item = Item.find(params[:id])
     if(!@item.nil? && @item.user_id == current_user.id)
       @item.destroy
       respond_to do |format|
          format.js
          format.xml
       end
     else
       raise ActionController::RoutingError.new('Forbidden')
     end
   rescue ActiveRecord::ResourceNotFound
     redirect_to :action => 'not_found', :status => 404 # do whatever you want here
   rescue ActionController::RoutingError
     redirect_to :action => 'forbidden', :status => 403 # do whatever you want here
   end
 end

除此之外,还提到您正在构建API,因此当您解决错误时,您可能希望呈现xml错误信息。类似的东西:

# in application_controller.rb
rescue_from ActionController::RoutingError, :with => :render_forbidden_error

private

def render_forbidden_error(e)
  render :status => e.status, :xml => e
end
祝你好运。 Udachi。