risposta

51

Nel application_conroller.rb aggiungere la seguente:

# 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 

Io di solito anche Salvataggio seguenti eccezioni, ma che sta a voi:

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

Creare il controller errori:

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

Poi 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 è quello di creare not_found.html.haml (o qualsiasi motore di template si usa) sotto /views/errors/:

%span 404 
    %br 
    Page Not Found 
+4

Questo non funziona in Rails 4.2.5. Sto indovinando che è perché l'eccezione è sollevata da ActionDispatch prima che venga eseguito qualsiasi codice del controller. – depquid

+0

@depquid L'ho scritto ai tempi di Rails 4.0.x, ma l'ho appena testato con Rails 4.2.5 - Suppongo che tu non abbia aggiunto route e non abbia creato il file 'errors_controller.rb' :) Se questo è il caso - assicurati di ritirare il downvote, a meno che tu non abbia più motivi per lasciarlo. –

+6

Spiacente, non ho impostato correttamente il percorso. Ma perché, 'rescue_from ActionController :: RoutingError, con: -> {render_404}' se stai indirizzando direttamente all'azione? – depquid

2

stavo ottenendo questo errore. Ho copiato favicon image in app/assets/images e funziona per me.

-2

@Andrey Deineko, la soluzione sembra funzionare solo per i valori RoutingError sollevati manualmente all'interno di un controller. Se provo con l'url my_app/not_existing_path, ottengo ancora il messaggio di errore standard.

Suppongo che ciò avvenga perché l'applicazione non raggiunge nemmeno i controller, poiché Rails solleva l'errore in precedenza.

Il trick che ha risolto il problema per me è stato quello di 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 predefiniti.

Poi nel ErrorsController è possibile utilizzare respond_to per servire html, JSON ... richieste:

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 
+0

potresti spiegare '@requested_path = request.path' e la sua chiamata corrispondente' format.json {render json: {routing_error: @requested_path}} '? –

+0

Ho appena usato '@ requested_path' nel template (error_404.html.haml). Per quanto riguarda il json, se sono sicuro che non voglio che venga restituita una pagina intera, ad esempio da ajax, posso chiedere json restituito e ricevere il messaggio di errore – Misu

Problemi correlati