38 votes

Dynamique des pages d'erreur dans Rails 3

Dans Les Rails 2.3.x, vous pouvez remplacer render_optional_error_file comme:

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

Cependant, Rails 3 n'a plus de render_optional_error_file. Au lieu de cela, vous avez besoin de redéfinir rescue_action_in_public, que vous pouvez le faire comme ceci:

# 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

Cela fonctionne, mais ne pas utiliser l'application de mise en page. Toutefois, si vous spécifiez le chemin disposition comme suit:

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

Vous obtenez un Error during failsafe response: ActionView::Template::Error.

La ligne 4 de l'application.html.erb:4 est la suivante:

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

Quelle que soit ActionView normalement utilise pour rendre les modèles n'est pas chargé.

La trace de la pile est:

  /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'

55voto

The Doctor What Points 4454

Dans les rails 3.2, c'est plus simple que cela:

Ajoutez à cela config/application.rb:

config.exceptions_app = self.routes

Qui provoque les erreurs à être acheminées par l'intermédiaire du routeur. Ensuite, il suffit d'ajouter à l' config/routes.rb:

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

J'ai eu cette info à partir de l'élément n ° 3 sur le blog "Mes cinq préférés fonctionnalités cachées dans les Rails 3.2", par José Valim.

51voto

mnelson Points 2224

Je conseille rescue_from à la place. Vous serait tout simplement de sauvetage erreurs spécifiques au lieu d'écraser les rescue_action_in_public. Ceci est particulièrement utile lorsque vous traitez avec défini par l'utilisateur des erreurs d'un contrôleur ou d'erreurs spécifiques.

# 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

3voto

Harish Shetty Points 38877

L'exception déclarant a une méthode appelée notify_about_exception d'initier la notification d'erreur sur demande.

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

0voto

Neeraj Kumar Points 103

J'ai également été confrontés à un tel problème. Le problème, c'est à cause de attachment_fu gem ou un plugin. Il vous suffit de désinstaller et de l'utiliser tout autre plugin ou gem permettra de résoudre votre problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X