如何正确呈现自定义404和500页?

时间:2012-02-11 11:22:16

标签: ruby-on-rails http-status-code-404 http-error

是否有办法告诉Rails呈现您的自定义错误页面(例如,您在ErrorsController中编写的错误页面)?我搜索了很多主题,看起来有点工作的是添加到ApplicationController之类的内容

if Rails.env.production?
  rescue_from Exception, :with => :render_error
  rescue_from ActiveRecord::RecordNotFound, :with => :render_not_found
  rescue_from ActionController::UnknownController, :with => :render_not_found
  rescue_from ActionController::UnknownAction, :with => :render_not_found
end

然后按照您想要的方式编写方法render_errorrender_not_found。在我看来,这似乎是一个非常不优雅的解决方案。此外,这很糟糕,因为您必须确切知道可能发生的所有错误是什么。这是一个临时解决方案。

此外,实际上没有简单的方法来拯救ActionController::RoutingError。我看到一种方法是添加像

这样的东西
get "*not_found", :to => "errors#not_found"

routes.rb。但是如果你想手动提升ActionController::RoutingError呢?例如,如果非管理员的人试图通过猜测URL来“管理”控制器。在那些情况下,我更喜欢提出404以上而不是某种类型的“未经授权的访问”错误,因为这实际上会告诉该人他猜到了URL。如果你手动提高它,它会尝试渲染500页,我想要一个404。

有没有办法告诉Rails:“在所有情况下,你通常会渲染404.html500.html,渲染我的自定义404和500页”? (当然,我删除了404.html文件夹中的500.htmlpublic页面。)

1 个答案:

答案 0 :(得分:1)

不幸的是,没有任何我知道的方法可以被覆盖以提供你想要的东西。你可以使用around过滤器。您的代码看起来像这样:

class ApplicationController < ActionController::Base
  around_filter :catch_exceptions

  protected
    def catch_exceptions
      yield
    rescue => exception
      if exception.is_a?(ActiveRecord::RecordNotFound)
        render_page_not_found
      else
        render_error
      end
    end
end

您可以根据自己的方法处理每个错误。然后,您的#render_page_not_found#render_error方法必须类似于

render :template => 'errors/404'

然后,您需要在app/views/errors/404.html.[haml|erb]

处拥有一个文件
相关问题