2010-09-12 13 views
73

C'è un modo per catturare tutte le eccezioni uncatched in un controller rotaie, come questo:Cattura tutte le eccezioni in un controller rotaie

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

Grazie

risposta

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

La regola non è MAI catturare eccezioni? – RonLugge

+1

ma come posso prendere tutto il tipo solo nel blocco 'rescue => e'? – Matrix

+4

@RonLugge dipende interamente dalla situazione attuale. applicare "mai" come regola empirica è una cattiva idea. –

9

rescue senza argomenti salverà alcun errore.

Quindi, ti consigliamo:

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

domanda stantio, ma questa risposta non è corretta. salvataggio senza argomento gestisce solo StandardError http://robots.thoughtbot.com/rescue-standarderror-not-exception – karmajunkie

178

È inoltre possibile definire un metodo 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 

A seconda del tuo obiettivo, potresti anche considerare di NON gestire eccezioni su base controller. Invece, usa qualcosa come la gemma exception_handler per gestire coerentemente le risposte alle eccezioni. Come bonus, questo approccio gestirà anche le eccezioni che si verificano nel livello middleware, come l'analisi delle richieste o gli errori di connessione al database che l'applicazione non vede. La gemma exception_notifier potrebbe anche essere di interesse.

+3

Questo è ancora più pratico in quanto consente di rilevare le eccezioni in modo DRY. – m33lky

+0

E se utilizzo rescue_from senza parametri? questo si comporterebbe come il salvataggio? prendere tutti gli errori? – minohimself

+2

Non è una cattiva pratica per 'rescue_from Exception'? La mia comprensione è che è meglio salvare da "StandardError", quindi cose come "SyntaxError" e "LoadError" non vengono catturate. – lobati

19

È possibile intercettare le eccezioni per 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

Attenzione a non salvare direttamente da "Exception"; vedi http://stackoverflow.com/questions/10048173/why-is-it-bad-style-to-rescue-exception-e-in-ruby –

0

In realtà, se si vuole veramente a catturare tutto, basta creare il proprio eccezioni app, che ti permette di personalizzare il comportamento che di solito è gestita dal PublicExceptions middleware: https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/public_exceptions.rb

Un mucchio di altre gemme risposte di condivisione che fanno questo per te, ma non c'è davvero alcun motivo per cui non puoi semplicemente guardarli e farlo da soli.

Un avvertimento: assicurarsi di non generare mai un'eccezione nel gestore di eccezioni. In caso contrario, si ottiene un brutto FAILSAFE_RESPONSE https://github.com/rails/rails/blob/4-2-stable/actionpack/lib/action_dispatch/middleware/show_exceptions.rb#L4-L22

BTW, il comportamento del controllore viene da salvabile: https://github.com/rails/rails/blob/4-2-stable/activesupport/lib/active_support/rescuable.rb#L32-L51

Problemi correlati