38

render_optional_error_fileRails 2.3.xでは、次のようにオーバーライドできます。

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

ただし、Rails3にはもうありません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'
4

4 に答える 4

55

Rails 3.2では、それよりも簡単です。

これをに追加しconfig/application.rbます:

config.exceptions_app = self.routes

これにより、エラーがルーター経由でルーティングされます。次に、に追加しconfig/routes.rbます:

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

この情報は、JoséValimによるブログ投稿「Rails3.2の私のお気に入りの5つの隠された機能」のアイテム#3から入手しました。

于 2012-06-15T13:46:53.193 に答える
51

代わりにrescue_fromを使用することをお勧めします。レスキュー_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

于 2011-03-19T06:58:05.063 に答える
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
于 2011-03-20T06:37:42.370 に答える
0

私もそのような問題に直面しました。問題はattachment_fugemまたはプラグインが原因です。それをアンインストールして、他のプラグインまたはgemを使用するだけで、問題が解決します。

于 2014-08-03T05:08:52.027 に答える