web-dev-qa-db-fra.com

rescue_from ActionController :: RoutingError dans Rails 4

J'ai l'erreur suivante:

ActionController::RoutingError (No route matches [GET] "/images/favicon.ico")

Je veux afficher la page d'erreur 404 pour les liens qui n'existent pas.

Comment puis-je y arriver?

19
Anna

Dans application_conroller.rb, ajoutez ce qui suit: 

  # You want to get exceptions in development, but not in production.
  unless Rails.application.config.consider_all_requests_local
    rescue_from ActionController::RoutingError, with: -> { render_404  }
  end

  def render_404
    respond_to do |format|
      format.html { render template: 'errors/not_found', status: 404 }
      format.all { render nothing: true, status: 404 }
    end
  end

Je sauve aussi généralement les exceptions suivantes, mais cela dépend de vous:

rescue_from ActionController::UnknownController, with: -> { render_404  }
rescue_from ActiveRecord::RecordNotFound,        with: -> { render_404  }

Créez le contrôleur d'erreurs:

class ErrorsController < ApplicationController
  def error_404
    render 'errors/not_found'
  end
end

Puis dans routes.rb

  unless Rails.application.config.consider_all_requests_local
    # having created corresponding controller and action
    get '*path', to: 'errors#error_404', via: :all
  end

Et la dernière chose à faire est de créer not_found.html.haml (ou le moteur de template que vous utilisez) sous /views/errors/:

  %span 404
  %br
  Page Not Found
54
Andrey Deineko

@Andrey Deineko, votre solution semble ne fonctionner que pour les RoutingErrors élevés manuellement dans un contrôleur. Si je l’essaie avec l’URL my_app/not_existing_path, j’obtiens toujours le message d’erreur standard.

J'imagine que cela est dû au fait que l'application n'atteint même pas les contrôleurs, car Rails soulève l'erreur auparavant.

Le astuce qui a résolu le problème pour moi a été d’ajouter la ligne suivante à la fin des itinéraires:

Rails.application.routes.draw do
  # existing paths
  match '*path' => 'errors#error_404', via: :all
end

pour attraper toutes les demandes non prédéfinies.

Ensuite, dans ErrorsController, vous pouvez utiliser respond_to pour traiter les requêtes html, json ...:

class ErrorsController < ApplicationController
  def error_404
    @requested_path = request.path
    repond_to do |format|
      format.html
      format.json { render json: {routing_error: @requested_path} }
    end
  end
end
1
Misu

Je recevais cette erreur. J'ai copié favicon image in app/assets/images et cela fonctionne pour moi.

1
Anuja