【问题标题】:Custom Error Pages in Rails?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 时会发生这种情况。

【问题讨论】:

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


    【解决方案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 引擎。也许您将需要它用于较新的项目。在我看来,这是处理错误的好选择。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2013-09-06
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多