rescue_from ActionController :: RoutingError in Rails 4

Ho il seguente errore:

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

Voglio mostrare la pagina error404 per i collegamenti che non esistono.

Come posso ottenerlo?

In application_conroller.rb aggiungi quanto segue:

  # 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 

Solitamente salvi anche le seguenti eccezioni, ma dipende da te:

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

Crea il controller degli errori:

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

Quindi in 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 

E l'ultima cosa è creare not_found.html.haml (o qualsiasi motore di template che usi) sotto /views/errors/ :

  %span 404 %br Page Not Found 

Stavo ottenendo questo errore. Ho copiato l’ immagine di favicon in app/assets/images e funziona per me.

@Andrey Deineko, la tua soluzione sembra funzionare solo per il RoutingError s sollevato manualmente all’interno di un controller. Se provo con l’url my_app/not_existing_path , ricevo comunque il messaggio di errore standard.

Immagino che questo sia dovuto al fatto che l’applicazione non raggiunge nemmeno i controller, dal momento che Rails solleva l’errore in precedenza.

Il trucco che mi ha risolto il problema era aggiungere la seguente riga alla fine dei percorsi:

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

per catturare tutte le richieste non predefinite.

Quindi in respond_to puoi usare respond_to per servire le richieste 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