在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
这样可行,但不使用应用程序的布局。但是,如果指定布局路径如下:
body = template.render(:file => file, :layout => "layouts/application") # line 15
你得到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'
答案 0 :(得分:55)
在rails 3.2中,它比那更容易:
将此添加到config/application.rb
:
config.exceptions_app = self.routes
这会导致错误通过路由器路由。然后,您只需添加到config/routes.rb
:
match "/404", :to => "errors#not_found"
我通过ByJoséValim在博客文章“My five favorite hidden features in Rails 3.2”中的第3项获得了此信息。
答案 1 :(得分:51)
我建议改用 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
答案 2 :(得分:3)
异常通知程序有一个名为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
答案 3 :(得分:0)
我也遇到过这样的问题。问题是因为attachment_fu gem或插件。只需卸载它并使用任何其他插件或gem即可解决您的问题。