Rails中的自定义错误页面?

时间:2010-02-10 16:00:34

标签: ruby-on-rails error-handling routing

我需要在rails应用程序中实现一个自定义错误页面,允许我使用erb。

我一直在关注本教程(http://blog.tommilewski.net/2009/05/custom-error-pages-in-rails/),我无法让它在本地(或远程)工作。我正在运行Rails 2.3.5

这是方法的要点。

1)在'application_controller'中,我超越了“render_optional_error_file(status_code)”方法,并将可见性设置为“protected”,就像这样。

protected

def render_optional_error_file(status_code)
  known_codes = ["404", "422", "500"]
  status = interpret_status(status_code)

  if known_codes.include?(status_code)
    render :template => "/errors/#{status[0,3]}.html.erb", :status => status, :layout => 'errors.html.erb'
  else
    render :template => "/errors/unknown.html.erb", :status => status, :layout => 'errors.html.erb'
  end
end

def local_request?
  true
end

我还在名为errors的视图中创建了一个文件夹,并创建了以下视图:404.html.erb422.html.erb500.html.erbunknown.html.erb我创建了一个新视图布局“errors.html.erb”

我似乎无法让它发挥作用。我一直试图通过导航到http://localhost:3000/foobar来触发404页面 - 但是,我似乎没有获得新的404.html.erb,而是出现了标准的apache 500错误。当我同时尝试mongrel_rails startmongrel_rails start -e production时会发生这种情况。

4 个答案:

答案 0 :(得分:32)

我建议使用异常来呈现此类错误页面,这样您就可以使用继承来对错误消息进行分组......

首先,声明一些(我通常在application_controller.rb中执行)

class Error404 < StandardError; end
class PostNotFound < Error404; end

然后将代码添加到ApplicationController以处理它们

class ApplicationController < ActionController::Base

  # ActionController::RoutingError works in Rails 2.x only.
  # rescue_from ActionController::RoutingError, :with => :render_404
  rescue_from Error404, :with => :render_404
  rescue_from PostNotFound, :with => :render_post_not_found


  def render_404
    respond_to do |type| 
      type.html { render :template => "errors/error_404", :status => 404, :layout => 'error' } 
      type.all  { render :nothing => true, :status => 404 } 
    end
    true
  end

  def render_post_not_found
    respond_to do |type| 
      type.html { render :template => "errors/shop_not_found", :status => 404, :layout => 'error' } 
      type.all  { render :nothing => true, :status => 404 } 
    end
    true
  end
end

这会使用错误布局呈现错误/ error_404。应该让你开始:))

在你的target_controller中:

raise PostNotFound unless @post

修改

Rails 3的注释

有关ActionController :: RoutingError不适用于rails 3的原因的更长解释: Rails 3.0 Exception Handling

Rails ticket 4444

  

“如果您的应用程序依赖于扩展您的应用程序的引擎   自己的路线,事情会破裂,因为这些路线永远不会得到   被解雇了!“

答案 1 :(得分:2)

首先 - 你删除了文件:'public / 500.html'如果该文件存在,它将覆盖你尝试做的任何其他事情。

其次,如果您需要微调对不同类型错误的响应,那么在控制器中使用显式的“rescue_from”(如另一条评论中所述)是一个不错的选择。

答案 2 :(得分:1)

由于应用程序错误,您很可能会收到500错误。 你检查过日志文件吗?

<强>更新

您确定您运行的是2.3.5而不是正好安装的旧版本吗? Mongrel应该说它在启动时运行的是哪个版本,否则应该在config / environment.rb文件中说明。

代码中可能存在一些错误,可能会产生500错误。我已经改变了这一点,并且还纠正了我认为你的其他一些事情:)

def render_optional_error_file(status_code)
  known_codes = ["404", "422", "500"]
  status = interpret_status(status_code)

  if known_codes.include?(status) # Here it should be status, not status_code (which is a symbol)
    render :template => "errors/#{status[0,3]}", :status => status, :layout => 'errors' # No need to mention ".html.erb", you can do it, but it is not necessary since rails will guess the correct format.
  else
    render :template => "errors/unknown", :status => status, :layout => 'errors'
  end
end

def local_request?
  # This must return false instead of true so that the public viewer is called 
  # instead of the developer version.
  false 
end

答案 3 :(得分:0)

新版轨道版本完整性的目的:

http://www.frick-web.com/en/blog/nifty_errorpages-gem

这是一个用于处理错误页面的小型rails引擎。也许你需要它来进行更新的项目。在我看来,处理错误是一个很好的选择。