Rails 中的自定义错误页面?

Posted

技术标签:

【中文标题】Rails 中的自定义错误页面?【英文标题】:Custom Error Pages in Rails? 【发布时间】:2011-01-15 08:17:32 【问题描述】:

我需要在我的 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

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 时会发生这种情况。

【问题讨论】:

【参考方案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

【讨论】:

我的意思是这个应用程序错误是由root错误引起的 好吧,你是对的!我删除了我的问题,因为它不再准确,我真的不确定 OP 的问题是什么。感谢赐教^^ 是的,我似乎遇到了路由错误……这是我在跟踪开发日志时看到的内容;处理 ApplicationController#index (for 127.0.0.1 at 2010-02-10 12:35:35) [GET] ActionController::RoutingError (No route matches "/foobar" with :method=>:get): 渲染救援/ layout (not_found) /!\ FAILSAFE /!\ Wed Feb 10 12:35:35 -0500 2010 Status: 500 Internal Server Error 我该如何解决这个问题?然后进行测试,看看它是否有效? 嗯,您是否按照我的建议更正了路径?我相信这是触发 500 错误的方法。我不确定你为什么没有得到它的踪迹,但这可能是因为该方法也应该处理它。【参考方案2】:

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

首先声明一些(我一般在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

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

在你的 target_controller 中:

raise PostNotFound unless @post

编辑

Rails 3 的注意事项

关于为什么 ActionController::RoutingError 不适用于 rails 3 的详细解释: Rails 3.0 Exception Handling.

Rails ticket 4444

“如果您的应用程序依赖于扩展您的应用程序的引擎 自己的路线,事情会中断,因为那些路线永远不会得到 开除!”

【讨论】:

当通过不正确的路线时,404 不会出现在开发中,这是正确的吗? Error404 在 ActionController 中定义,rails 本身不会产生 404 错误(静态服务器可能)。您应该像“raise Error404 unless @post”一样使用它来模拟静态服务器。 顺便说一句,rescue_from ActionController:: 还不能在 Rails 3 中使用,对于那些使用该版本偶然发现这篇文章的人。见此链接:rails.lighthouseapp.com/projects/8994/tickets/… 谢谢。这里只是一个想法 - 我们实际上是否应该首先拯救最具体的 404 错误?我原以为我们会拯救 PostNotFound then Error404... @Stu:rescue_from只是简单的包装了ruby的begin..rescue,PostNotFound是Error404的子类,所以会调用对应的方法。【参考方案3】:

首先 - 您是否删除了文件:'public/500.html' 如果该文件存在,它将覆盖您尝试执行的任何其他操作。

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

【讨论】:

【参考方案4】:

更新 Rails 版本的完整性目的:

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

这是一个用于处理错误页面的小 Rails 引擎。也许您将需要它用于较新的项目。在我看来,这是处理错误的好选择。

【讨论】:

以上是关于Rails 中的自定义错误页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用页面应用程序中的自定义页面更改默认的 404 错误页面

PHP中的自定义404错误页面

旧 ASP.Net 应用程序中的自定义错误页面不起作用

Lumen 中的自定义 404 页面

从 servlet java 抛出的自定义 503 错误页面

asp.net MVC3 上的自定义错误页面