Ein Freund wies mich auf eine elegante Lösung hin, die nicht nur 404, sondern auch 500 Fehler behandelt. Tatsächlich behandelt es jeden Fehler. Der Schlüssel ist, dass jeder Fehler eine Ausnahme generiert, die sich durch den Stapel von Rack-Middlewares nach oben ausbreitet, bis sie von einem von ihnen behandelt wird. Wenn Sie mehr erfahren möchten, können Sie sich diesen hervorragenden Screencast ansehen . Rails verfügt über eigene Handler für Ausnahmen, die Sie jedoch mit der weniger dokumentierten exceptions_app
Konfigurationsoption überschreiben können . Jetzt können Sie Ihre eigene Middleware schreiben oder den Fehler wie folgt zurück in die Schienen leiten:
config.exceptions_app = self.routes
Dann müssen Sie nur noch diese Routen in Ihrem config/routes.rb
:
get "/404" => "errors#not_found"
get "/500" => "errors#exception"
Und dann erstellen Sie einfach einen Controller, um dies zu handhaben.
class ErrorsController < ActionController::Base
def not_found
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "not-found"}.to_json, :status => 404
else
render :text => "404 Not found", :status => 404
end
end
def exception
if env["REQUEST_PATH"] =~ /^\/api/
render :json => {:error => "internal-server-error"}.to_json, :status => 500
else
render :text => "500 Internal Server Error", :status => 500
end
end
end
Eine letzte Sache, die hinzugefügt werden muss: In der Entwicklungsumgebung rendert Rails normalerweise nicht die 404- oder 500-Seiten, sondern druckt stattdessen eine Rückverfolgung. Wenn Sie möchten, dass Sie ErrorsController
im Entwicklungsmodus in Aktion sind, deaktivieren Sie das Backtrace-Material in Ihrer config/enviroments/development.rb
Datei.
config.consider_all_requests_local = false
Ich möchte einen separaten API-Controller erstellen, der das Format (json) und die API-spezifischen Methoden festlegt:
class ApiController < ApplicationController respond_to :json rescue_from ActiveRecord::RecordNotFound, with: :not_found # Use Mongoid::Errors::DocumentNotFound with mongoid def not_found respond_with '{"error": "not_found"}', status: :not_found end end
RSpec-Test:
it 'should return 404' do get "/api/route/specific/to/your/app/", format: :json expect(response.status).to eq(404) end
quelle
api/non_existant_route
?rescue_from ActiveRecord::RecordNotFound, with: not_found
muss sein,with: :not_found
aber es ist nur eine Bearbeitung mit einem Zeichen: PKlar, es wird ungefähr so aussehen:
class ApplicationController < ActionController::Base rescue_from NotFoundException, :with => :not_found ... def not_found respond_to do |format| format.html { render :file => File.join(Rails.root, 'public', '404.html') } format.json { render :text => '{"error": "not_found"}' } end end end
NotFoundException
ist nicht der wirkliche Name der Ausnahme. Dies hängt von der Rails-Version und dem gewünschten Verhalten ab. Mit einer Google-Suche ziemlich einfach zu finden.quelle
rescue_from
Dokumenten .Versuchen Sie, am Ende Ihrer
routes.rb
:match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }
quelle
match
in derRails.application.routes
Datei jetzt die HTTP-Methode über denvia:
Parameter angeben . Dies wird auch als Fehler angezeigt, wenn Sie versuchen, die obige Zeile zu verwenden.