unitarias rails pruebas elaborando crear con apis ruby-on-rails

ruby-on-rails - pruebas - rails web service json



Es necesario devolver el error 404 con formato JSON en Rails (4)

Tengo una interfaz HTML normal y una API JSON en mi aplicación Rails. Ahora, si alguien llama a /api/not_existent_method.json , devuelve la página HTML 404 predeterminada. ¿Hay alguna manera de cambiar esto a algo así como {"error": "not_found"} mientras se deja la página 404 original para la interfaz HTML intacta?


Claro, se verá algo como esto:

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 no es el nombre real de la excepción. Variará con la versión de Rails y el comportamiento exacto que desee. Bastante fácil de encontrar con una búsqueda en Google.


Intenta poner al final de tus routes.rb :

match ''*foo'', :format => true, :constraints => {:format => :json}, :to => lambda {|env| [404, {}, [''{"error": "not_found"}'']] }


Me gusta crear un controlador API independiente que establezca el formato (json) y los métodos específicos de la API:

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

Prueba de RSpec:

it ''should return 404'' do get "/api/route/specific/to/your/app/", format: :json expect(response.status).to eq(404) end


Un amigo me señaló una solución elegante que no solo maneja 404 sino también 500 errores. De hecho, maneja todos los errores. La clave es que cada error genera una excepción que se propaga hacia arriba a través de la pila de middlewares de rack hasta que es manejado por uno de ellos. Si está interesado en aprender más, puede ver este excelente screencast . Rails tiene sus propios manejadores para las excepciones, pero puede anularlos mediante la opción de configuración exceptions_app menos documentada. Ahora puede escribir su propio middleware o puede enrutar el error en rieles, como este:

# In your config/application.rb config.exceptions_app = self.routes

Entonces solo tienes que hacer coincidir estas rutas en tu config/routes.rb :

get "/404" => "errors#not_found" get "/500" => "errors#exception"

Y luego solo creas un controlador para manejar esto.

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

Una última cosa para agregar: en el entorno de desarrollo, los rieles usualmente no representan las páginas 404 o 500, sino que imprimen una traza inversa. Si desea ver su ErrorsController en acción en el modo de desarrollo, deshabilite la ruta de retroceso en su archivo config/enviroments/development.rb .

config.consider_all_requests_local = false