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

时间:2021-02-17 00:17:37

I have RoR 3.0 web application which is acting as an OAuth API provider. Now, in API I'd like to return correct HTTP error codes to the API consumer. How do I do this?

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

Here is example:

这是一个例子:

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

So, in case of error I'm trying to return Forbidden 403 code. Still, when running this I'm getting always 404 Not Found returned. How do I return the correct code?

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

Or is this somehow webserver configurable thing?

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

5 个解决方案

#1


34  

You should render page with correct status.

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

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

#2


46  

When you're just giving a status code and there is no body, a convenient way is

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

head 403

This method also accepts the symbolic names for status codes, such as

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

head :forbidden

#3


11  

According to ActionController::Head docs just use this pattern in actions

根据ActionController :: Head文档,只需在动作中使用此模式

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

Example:

例:

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

return is used to make sure that no remaining code in the action will be run.

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

#4


1  

well, you can use

好吧,你可以使用

:status =>500

But, In default Rails take care of the error type rendering itself.

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

Errors default pages are in the public directory. 500.html,404.html etc..

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

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

有关以下内容的更多信息:状态,如何使用它请单击此处

#5


1  

I think you have two problems here: first is that your @item = Item.find(params[:id]) line is raising 404 and execution never gets to where intended (if statement). Second is that you are raising exceptions and never catch them. Try:

我认为你有两个问题:首先是你的@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

Something along those lines, but you also mentioned that you are building the API, so when you are rescuing the error, you may want to render xml error info. Something like:

这些内容,但您还提到您正在构建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

Good luck. Udachi.

祝你好运。 Udachi。

#1


34  

You should render page with correct status.

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

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

#2


46  

When you're just giving a status code and there is no body, a convenient way is

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

head 403

This method also accepts the symbolic names for status codes, such as

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

head :forbidden

#3


11  

According to ActionController::Head docs just use this pattern in actions

根据ActionController :: Head文档,只需在动作中使用此模式

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

Example:

例:

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

return is used to make sure that no remaining code in the action will be run.

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

#4


1  

well, you can use

好吧,你可以使用

:status =>500

But, In default Rails take care of the error type rendering itself.

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

Errors default pages are in the public directory. 500.html,404.html etc..

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

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

有关以下内容的更多信息:状态,如何使用它请单击此处

#5


1  

I think you have two problems here: first is that your @item = Item.find(params[:id]) line is raising 404 and execution never gets to where intended (if statement). Second is that you are raising exceptions and never catch them. Try:

我认为你有两个问题:首先是你的@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

Something along those lines, but you also mentioned that you are building the API, so when you are rescuing the error, you may want to render xml error info. Something like:

这些内容,但您还提到您正在构建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

Good luck. Udachi.

祝你好运。 Udachi。