17

ich folgende Fehlermeldung haben:rescue_from Action :: RoutingError in Rails 4

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

Ich möchte für Links error404 Seite zeigen, die nicht vorhanden sind.

Wie kann ich das erreichen?

Antwort

51

In application_conroller.rb fügen Sie den folgenden:

# 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 

ich in der Regel auch Ausnahmen retten folgen, aber das ist bis zu Ihnen:

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

Erstellen Sie den Fehler Controller:

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

Dann 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 

Und das letzte, was zu schaffen not_found.html.haml (oder was auch immer Template-Engine Sie verwenden) unter /views/errors/:

%span 404 
    %br 
    Page Not Found 
+4

Das funktioniert nicht in Rails 4.2.5. Ich vermute, dass die Ausnahme von ActionDispatch ausgelöst wird, bevor ein Controller-Code ausgeführt wird. – depquid

+0

@depquid Ich habe es in den Zeiten von Rails 4.0.x geschrieben, aber habe es gerade mit Rails 4.2.5 getestet - ich nehme an, du hast keine Route hinzugefügt und nicht die 'errors_controller.rb' erstellt :) Wenn das der Fall ist - Bitte vergewissern Sie sich, dass Sie den Downvote zurückziehen, es sei denn, Sie haben weitere Gründe, ihn zu verlassen. –

+6

Entschuldigung, ich habe die Route nicht korrekt eingerichtet. Aber warum, rescue_from ActionController :: RoutingError, mit: -> {render_404} 'wenn Sie direkt zur Aktion weitergeleitet werden? – depquid

2

ich diesen Fehler. Ich kopierte favicon Bild in app/assets/images und seine Arbeit für mich.

-2

@Andrey Deineko, scheint Ihre Lösung nur für die RoutingError s manuell in einem Conrtoller angehoben zu arbeiten. Wenn ich es mit der URL my_app/not_existing_path versuche, bekomme ich immer noch die Standardfehlermeldung.

Ich denke, das liegt daran, dass die Anwendung nicht einmal die Controller erreicht, da Rails den Fehler zuvor ausgelöst hat.

Die trick, die das Problem gelöst für mich die folgende Zeile am Ende der Routen hinzuzufügen war:

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

zu fangen alle nicht vordefiniert Anfragen.

Dann in der ErrorsController können Sie respond_to verwenden html, json ... Anfragen zu bedienen:

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

könnten Sie '@ requested_path = request.path' und den entsprechenden Aufruf' format.json {render json: {routing_error: @requested_path}} '' erklären? –

+0

Ich habe gerade '@ requested_path' in der Vorlage (error_404.html.haml) verwendet. Wie für den JSON, wenn ich sicher bin, dass ich nicht eine ganze Seite zurückgeben möchte, zum Beispiel von AJAX, kann ich fragen, dass JSON zurückgegeben wird, und die Fehlermeldung erhalten – Misu