2016-04-11 7 views
2

Meine Rails-Website (dieses Problem ist rein Ruby basiert) verwendet die AWS-SES (Gems-Aktion AWS) Edelstein in Test/Entwicklungsumgebung, und ich fange mögliche Fehler von E-Mail wie diese LieferungenRettung von einem Fehler, der möglicherweise nicht definiert wird

def try_delivering_email(options = {}) 
    begin 
     yield 
     return false 
    rescue EOFError, 
      ... 
      AWS::SES::ResponseError, 
      ... => e 
     log_exception(e, options) 
     return e 
    end 
end 

Jetzt ist das Problem, dass dieses Juwel nur für bestimmte Umgebungen definiert ist, mit anderen Worten AWS in Entwicklung nicht existiert, und der Fehlerprüfungscode wird daher einen Fehler (haha) für nicht definiert konstante werfen .

Ich habe versucht, diese Zeile für (AWS::SES::ResponseError if defined?(AWS) substuting aber dann der nächste Fehler I erhalten

Klasse oder ein Modul für rescue-Klausel

erforderlich Wie kann ich um dieses auf die netteste Art bekommen möglich ?

+0

Warum können Sie AWS :: SES nicht in der Entwicklung verwenden? –

+0

Nun eigentlich kann ich, aber ich lade normalerweise keine Edelsteine ​​Ich weiß, dass ich nicht verwende (in der Entwicklung verwende ich immer 'letter_opener_web', ich möchte keine E-Mail für echt senden), also in meiner gemfile habe ich nur hinzugefügt 'aws-ses' Juwel unter der Test/Prod Gruppe –

Antwort

4

Die Ausnahmeliste einer Rettungs-Klausel muss nicht eine wörtliche/statische Liste sein:

excs = [EOFError] 
defined?(AWS) && excs << AWS::SES::Response 
# ... 
rescue *excs => e 

Die Splat-Operator * hier verwendet wird, ein Array in eine Liste zu konvertieren.

+0

Oh schön! Wir können diesen Splat-Operator nicht oft verwenden, aber er ist hier sehr praktisch! Rubys Magie :) –

2

Sie können nicht eine bedingte in einer rescue Klausel enthalten, aber Sie können Rettungs blind machen und dann picky erhalten, wie mit ihm unter Verwendung von herkömmlichen Ruby-Code zu behandeln:

rescue EOFError => e 
    log_exception(e) 

    e 
rescue => e 
    if (defined?(AWS) and e.is_a?(AWS::SES::Response)) 
    # ... 
    else 
    raise e 
    end 
end 

Es ist nicht die schönste Art und Weise, aber es macht den Job. Man konnte immer eine Menge, dass in einigen Modul einkapseln, die mehr ordentlich testet:

def loggable_exception?(e) 
    case (e) 
    when EOFError, AnotherError, EtcError 
    true 
    else 
    if (defined?(AWS) and e.is_a?(AWS::SES::Response)) 
     true 
    else 
     false 
    end 
    end 
end 

Dann können Sie diese Namen wie diese Methode tun sollte selbsterklärend sein:

rescue => e 
    if (loggable_exception?(e)) 
    log_exception(e) 

    e 
    else 
    raise e 
    end 
end 

Sie dieses eine machen könnte wenig sauberer, wenn log_exception die Ausnahme zurückgab, die es gegeben wurde. Vergessen Sie nicht, Ruby ist standardmäßig "return" und es muss nicht explizit sein, es sei denn, Sie tun es früh.

Verwandte Themen