ruby on rails - software - Captura todas las excepciones en un controlador de rieles
ruby on rails tutorial (5)
¿Hay alguna forma de detectar todas las excepciones no detectadas en un controlador de rieles, como este?
def delete
schedule_id = params[:scheduleId]
begin
Schedules.delete(schedule_id)
rescue ActiveRecord::RecordNotFound
render :json => "record not found"
rescue ActiveRecord::CatchAll
#Only comes in here if nothing else catches the error
end
render :json => "ok"
end
Gracias
En realidad, si realmente quieres ver todo , simplemente creas tu propia aplicación de excepciones, que te permite personalizar el comportamiento que generalmente maneja el middleware PublicExceptions: https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb
- ubicación en la pila https://github.com/rails/rails/blob/4-2-stable/railties/lib/rails/application/default_middleware_stack.rb#L98-L99
- configurando https://github.com/rails/rails/blame/4-2-stable/guides/source/configuring.md#L99
- que puede ser tan fácil como usar las rutas http://blog.plataformatec.com.br/2012/01/my-five-favorite-hidden-features-in-rails-3-2/ o un controlador personalizado (pero vea https://github.com/rails/rails/pull/17815 por razones para no usar las rutas)
Muchas de las otras respuestas comparten gemas que hacen esto por ti, pero realmente no hay ninguna razón para que no puedas mirarlas y hacerlo tú mismo.
Una advertencia: asegúrese de nunca generar una excepción en su manejador de excepciones. De lo contrario, obtienes un FAILSAFE_RESPONSE feo https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L4-L22
Por cierto, el comportamiento en el controlador proviene de rescatable: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51
Puede capturar excepciones por tipo:
rescue_from ::ActiveRecord::RecordNotFound, with: :record_not_found
rescue_from ::NameError, with: :error_occurred
rescue_from ::ActionController::RoutingError, with: :error_occurred
# Don''t resuce from Exception as it will resuce from everything as mentioned here "http://.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby" Thanks for @Thibaut Barrère for mention that
# rescue_from ::Exception, with: :error_occurred
protected
def record_not_found(exception)
render json: {error: exception.message}.to_json, status: 404
return
end
def error_occurred(exception)
render json: {error: exception.message}.to_json, status: 500
return
end
También puedes definir un método rescue_from.
class ApplicationController < ActionController::Base
rescue_from ActionController::RoutingError, :with => :error_render_method
def error_render_method
respond_to do |type|
type.xml { render :template => "errors/error_404", :status => 404 }
type.all { render :nothing => true, :status => 404 }
end
true
end
end
Dependiendo de cuál sea su objetivo, también puede considerar NO manejar excepciones por cada controlador. En su lugar, use algo como la gema exception_handler para gestionar las respuestas a las excepciones de forma coherente. Como beneficio adicional, este enfoque también manejará las excepciones que se producen en la capa de middleware, como el análisis de solicitudes o los errores de conexión a la base de datos que su aplicación no puede ver. La joya exception_notifier también puede ser de interés.
rescue
sin argumentos rescatará cualquier error.
Entonces, querrás:
def delete
schedule_id = params[:scheduleId]
begin
Schedules.delete(schedule_id)
rescue ActiveRecord::RecordNotFound
render :json => "record not found"
rescue
#Only comes in here if nothing else catches the error
end
render :json => "ok"
end
begin
# do something dodgy
rescue ActiveRecord::RecordNotFound
# handle not found error
rescue ActiveRecord::ActiveRecordError
# handle other ActiveRecord errors
rescue # StandardError
# handle most other errors
rescue Exception
# handle everything else
raise
end