Rails 3中的dynamic错误页面

在Rails 2.3.x中,你可以像这样覆盖render_optional_error_file

 # ApplicationController.rb protected def render_optional_error_file(status_code) render :template => "errors/500", :status => 500, :layout => 'application' end 

但是,Rails 3不再拥有render_optional_error_file 。 相反,您需要覆盖rescue_action_in_public ,您可以这样做:

 # config/initializers/error_page.rb module ActionDispatch class ShowExceptions protected def rescue_action_in_public(exception) status = status_code(exception).to_s template = ActionView::Base.new(["#{Rails.root}/app/views"]) if ["404"].include?(status) file = "/errors/404.html.erb" else file = "/errors/500.html.erb" end body = template.render(:file => file) render(status, body) end end end 

这工作,但不使用应用程序的布局。 但是,如果您像这样指定布局path:

 body = template.render(:file => file, :layout => "layouts/application") # line 15 

Error during failsafe response: ActionView::Template::Error出现Error during failsafe response: ActionView::Template::Error

application.html.erb:4的第4行是:

 <%= stylesheet_link_tag "app", "jquery-ui", "jquery.fancybox", :cache => "all" %> 

无论ActionView通常用于呈现模板,都无法加载。

堆栈跟踪是:

  /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `join' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:794:in `rails_asset_id' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:817:in `rewrite_asset_path' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:746:in `compute_public_path' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:424:in `path_to_stylesheet' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:875:in `ensure_stylesheet_sources!' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `each' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:874:in `ensure_stylesheet_sources!' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/helpers/asset_tag_helper.rb:512:in `stylesheet_link_tag' /data/sites/fundraisers-stage/releases/20110316194843/app/views/layouts/application.html.erb:4:in `_app_views_layouts_application_html_erb___19482063_70294907435920_0' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `send' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:135:in `render' /var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:54:in `instrument' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/template.rb:127:in `render' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/layouts.rb:80:in `_render_layout' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:62:in `_render_template' /var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument' /var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications/instrumenter.rb:21:in `instrument' /var/lib/gems/1.8/gems/activesupport-3.0.5/lib/active_support/notifications.rb:52:in `instrument' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:56:in `_render_template' /var/lib/gems/1.8/gems/actionpack-3.0.5/lib/action_view/render/rendering.rb:26:in `render' /data/sites/fundraisers-stage/releases/20110316194843/config/initializers/error_pages.rb:15:in `rescue_action_in_public' 

在rails 3.2中,比这更容易:

添加到config/application.rb

 config.exceptions_app = self.routes 

这会导致通过路由器发送错误。 然后你只需添加到config/routes.rb

 match "/404", :to => "errors#not_found" 

我从JoséValim的博客文章“ Rails 3.2中我最喜欢的五个隐藏function ”中的第3项获得了这个信息。

我会build议使用rescue_from来代替。 你只是从具体的错误救援,而不是覆盖rescue_action_in_public。 这在处理用户定义的错误或控制器特定的错误时特别有用。

 # ApplicationController rescue_from ActionController::RoutingError, :with => :render_404 rescue_from ActionController::UnknownAction, :with => :render_404 rescue_from ActiveRecord::RecordNotFound, :with => :render_404 rescue_from MyApp::CustomError, :with => :custom_error_resolution def render_404 if /(jpe?g|png|gif)/i === request.path render :text => "404 Not Found", :status => 404 else render :template => "shared/404", :layout => 'application', :status => 404 end end # UsersController rescue_from MyApp::SomeReallySpecificUserError, :with => :user_controller_resolution 

http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html

exception通知程序有一个名为notify_about_exception的方法来notify_about_exception需要启动错误通知。

 class ApplicationController < ActionController::Base include ExceptionNotification::Notifiable rescue_from Exception, :with => :render_all_errors def render_all_errors(e) log_error(e) # log the error notify_about_exception(e) # send the error notification # now handle the page if e.is_a?(ActionController::RoutingError) render_404(e) else render_other_error(e) end end def render_404_error(e) # your code end def render_other_error(e) # your code end end 

我也遇到过这样的问题。 问题是因为attachment_fugem或插件。 只要卸载它,并使用任何其他插件或gem将解决您的问题。