2010-09-12 25 views
73

¿Hay una manera de capturar todas las excepciones uncatched en un controlador de rieles, como este:capturar todas las excepciones en un controlador de rieles

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

Respuesta

75
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 
+25

¿No es NUNCA la regla que detecta excepción? – RonLugge

+1

, pero ¿cómo puedo capturar todo tipo en el bloque 'rescue => e' solamente? – Matrix

+4

@RonLugge depende completamente de la situación en cuestión. aplicar "nunca" como regla general es una mala idea. –

9

rescue sin argumentos rescatará cualquier error.

Por lo tanto, tendrá que:

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 
+6

pregunta rancio, pero esta respuesta es incorrecta. rescatar sin argumento maneja solo StandardError http://robots.thoughtbot.com/rescue-standarderror-not-exception – karmajunkie

178

También puede 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, es posible que también desee considerar NO manejar excepciones por cada controlador. En su lugar, use algo como la gema exception_handler para administrar las respuestas a las excepciones de manera consistente. 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 gema exception_notifier también podría ser de interés.

+3

Esto es aún más útil ya que permite detectar excepciones de manera SECA. – m33lky

+0

Y si uso rescue_from sin params? ¿Eso se comportará igual que el rescate? atrapar todos los errores? – minohimself

+2

¿No es una mala práctica 'rescue_from Exception'? Según tengo entendido, es mejor rescatar de 'StandardError', por lo que cosas como 'SyntaxError' y' LoadError' no se capturan. – lobati

19

Puede capturar las 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://stackoverflow.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 
+2

Cuidado de no rescatar directamente de 'Exception'; ver http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby –

0

En realidad, si realmente se desea capturar todo, que acaba de crear su propia excepciones aplicación, que te permite personalizar el comportamiento que normalmente está a cargo de la PublicExceptions middleware: https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb

Un montón de las otras gemas respuestas en acciones que hacen esto para ti, pero realmente no hay razón para que no puedas mirarlos y hacerlo tú mismo.

Una advertencia: asegúrese de nunca generar una excepción en su manejador de excepciones. De lo contrario se obtiene una fea FAILSAFE_RESPONSE 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 viene de rescatable: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51

Cuestiones relacionadas