Mam normalny interfejs HTML i interfejs API JSON w mojej aplikacji Rails. Teraz, jeśli ktoś zadzwoni pod numer /api/not_existent_method.json
, zwróci domyślną stronę HTML 404. Czy jest jakiś sposób, aby zmienić to na coś podobnego do {"error": "not_found"}
, pozostawiając oryginalną stronę 404 nienaruszonego frontendu HTML?Konieczność zwrócenia błędu 404 w formacie JSON w Railsach
Odpowiedz
przyjaciel wskazał mi w kierunku eleganckie rozwiązanie, które nie tylko obsłużyć 404, ale także 500 błędów. W rzeczywistości obsługuje każdy błąd. Kluczem jest to, że każdy błąd generuje wyjątek, który rozprzestrzenia się w górę przez stos middleware, aż zostanie obsłużony przez jeden z nich. Jeśli chcesz dowiedzieć się więcej, możesz obejrzeć this excellent screencast. Railsy mają własne procedury obsługi wyjątków, ale możesz je zastąpić mniej udokumentowaną opcją konfiguracji exceptions_app
. Teraz można napisać własny middleware czy można trasa błąd powrotem do szyn, tak:
# In your config/application.rb
config.exceptions_app = self.routes
Wtedy po prostu trzeba dopasować te trasy w swojej config/routes.rb
:
get "/404" => "errors#not_found"
get "/500" => "errors#exception"
a następnie po prostu utwórz kontroler do obsługi tego.
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 # You can render your own template here
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 # You can render your own template here
end
end
end
Ostatnią rzeczą, aby dodać: W środowisku programistycznym, szyny usally nie czyni 404 lub 500 stron, ale drukuje ślad zamiast. Jeśli chcesz zobaczyć swoją ErrorsController
w akcji w trybie programowania, wyłącz opcję śledzenia wstecznego w pliku config/enviroments/development.rb
.
config.consider_all_requests_local = false
Oczywiście, będzie to wyglądać mniej więcej tak:
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
jest nie prawdziwe imię wyjątku. Będzie się różnić w zależności od wersji Railsów i dokładnego zachowania, które chcesz. Bardzo łatwe do znalezienia dzięki wyszukiwarce Google.
Dzięki za pomysł, ale Używam Rails 3.2.2, gdzie obsługa wyjątków uległa zmianie. To już nie zadziała. – iblue
@iblue Działa to dobrze w Railsach 3.2+ i jest lepszym rozwiązaniem. Zobacz 'rescue_from' [docs] (http://apidock.com/rails/v3.2.3/ActiveSupport/Rescuable/ClassMethods/rescue_from), aby uzyskać więcej informacji. – Intelekshual
Działa tylko dla błędów 404, a nie dla 500 błędów. – iblue
Spróbuj umieścić na koniec twoich routes.rb
:
match '*foo', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, ['{"error": "not_found"}']] }
Dla każdego, kto to czyta, 'match' w pliku' Rails.application.routes' wymaga teraz określenia metody HTTP za pomocą parametru 'via:'. Będzie to również wyświetlane jako błąd podczas próby użycia powyższej linii. – sameers
Chciałbym utworzyć oddzielny kontroler interfejsu API, który ustawia format (json) oraz metod API-specyficzne:
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 testową:
it 'should return 404' do
get "/api/route/specific/to/your/app/", format: :json
expect(response.status).to eq(404)
end
To wydaje się działać tylko dla rekordów. Jak zarządzałbyś sprawą dla 'api/non_existant_route'? – Sebastialonso
wiersz 'rescue_from ActiveRecord :: RecordNotFound, z: not_found' musi być' with:: not_found' ale jest to tylko jedna edycja znaku: P – erroric
@erroric thanks! :) –
- 1. Jak mogę zwrócić format 404 JSON w Railsach 4?
- 2. Wymuszenie odpowiedzi HTTP w celu zwrócenia statusu 200 w Railsach
- 3. Pomoc w formacie JSON
- 4. Dane POST w formacie JSON
- 5. Wiosenna inicjalizacja błędu 404 niestandardowa odpowiedź błędu ReST
- 6. Użycie WebAPI lub MVC do zwrócenia JSON w ASP.NET
- 7. Jak zminimalizować wyjście JSON w Railsach?
- 8. Konieczność zsynchronizowane w zmiennej lokalnej
- 9. Złap nieznaną akcję w Railsach 3 dla niestandardowego 404
- 10. Uzyskaj metadane OData $ w formacie JSON
- 11. Wyjście bowerów jest w formacie JSON
- 12. Umieścić dane JSON w ukrytym formacie html?
- 13. Ukryj katalog nadpisywania wstawiania w formacie json
- 14. Konwersja listy ciąg w formacie json
- 15. W jaki sposób można wykonać dynamiczne strony 404, 500 itd. W Railsach?
- 16. Dezaktywuj domyślną obsługę błędu 404 Jetty
- 17. Pokaż stronę błędu 404 po błędzie [Autoryzuj]
- 18. Biblioteka Open-URI Ruby przerwana w 404 kodzie błędu HTTP
- 19. Niestandardowa strona błędu 404 nie działa w IIS 8.5
- 20. Obsługa JSON w szablonie JS/ERB w Railsach 3
- 21. Przechowywanie procentu w Railsach + MySQL
- 22. Jak zwrócić odpowiedź 403 w formacie JSON w Laravel 5.2?
- 23. Konieczność getter
- 24. Szyny 4 - Dostosowywanie (json) formatu obiektów odpowiedzi w Railsach
- 25. Zwracanie niestandardowej strony 404 z kodem statusu 404 w MVC?
- 26. JSON Funkcja wywołania błędu wywołania
- 27. Jak przechowywać przedmioty ze złomu w formacie json?
- 28. Jak wysłać tablicę obiektów w formacie JSON z PHP
- 29. jqgrid howto wysłać wszystkie rowsData w formacie json do serwera?
- 30. Pobierz dane KML Google Map w formacie JSON
Nie zapomnij także dodać kodu stanu do renderowania. W przeciwnym razie twój klient/przeglądarka nie będzie wiedział, że to 404/500. render: text => "404 not found",: status =>: not_found – arnab
Edytowałem swoją odpowiedź. – iblue
Powiedziałbym, że blok respond_to jest bardziej uniwersalny w funkcjach renderowania: respond_to do | format | format.json {render json: {błąd: "nieodnaleziony"}. To_json, status: 404} format.html {wyrenderowanie tekstu: "404 Nie znaleziono", status: 404} koniec –