2016-05-04 9 views
0

私は、ソースのタイプからデータを取得する関数を呼び出していますので、FileReaderというスーパークラスを作成し、それぞれFTP、SFTP、Googleドライブなどのクラスを作成しました。継承し、get_data関数を実装します。メソッド/クラス間で同じ例外をキャッチ

宝石から返された例外をキャッチして、外部要因をバグレポートとしてRollbarに報告しないようにしたいので、例外を救済して、ファイルが見つからないときに適切なメッセージをユーザーに返しますタイムアウトなどです。Rescueブロックはスーパークラスにあります。なぜなら、SocketError、EOFErrorなどの例外はすべてのサブクラスで共通するため、コードを乾燥させようとしているからです。

class FileReader 

    def get_data 
    nil 
    end 

    def read 
    data = nil 
    begin 
     data = get_data 
    rescue EOFError => e 
     # return error message 
    rescue SocketError => e 
     # return error message 
    rescue OpenURI::HTTPError => e 
     # return error message 
    rescue Net::FTPPermError => e 
     # return error message 
    rescue Net::SFTP::StatusException => e 
     # return error message 
    rescue Errno::ETIMEDOUT => e 
     # return error message 
    rescue Exception => e 
     puts e.message 
     puts e.backtrace.join("\n") 
     Rollbar.error(e, :source => self) 
     # return error message 
    end 
    return data 
    end 

end 

FtpFileReaderはget_data機能を実装するためにFileReaderのクラスを継承しています。

​​

と私のreadメソッドは、私のRailsモデルから呼び出されます。

しかし、そのような例外をキャッチすることは私にとって難しいことです。 呼び出すメソッドreadがこの例外をキャッチしていますが、FileReader#get_dataメソッドは同じ例外もキャッチしますが、その中にレスキューブロックを実装していますか?

readではなく、FileReader get_dataメソッドでこれらの例外を捕捉する必要がありますか?または、サブクラス自体でこれらの特定の例外をキャッチし、サブクラスの各get_dataメソッドでエラーメッセージを返しますか?最終的にキャッチするクラスは大きくなりますが、EOFErrorを複製すると、SocketErrorはあまり乾燥しません。このような場合に例外を処理する最良の方法は何でしょうか?

+0

そのエラーが(キャッチ以外のすべてのレスキュー例外条項)あなたのいずれかの句でキャッチする必要がありますだと思いますなぜ –

+0

@FrederickCheungは、あなたは何を意味するのですか? – nayiaw

+0

私は、エラーが「レスキュー例外」ビットに終わるべきではないと思うのはなぜですか? –

答えて

1

最初に、あなたが再挑戦していない限り、あなたがそれをやっている理由を尋ねない限り、Exceptionから救助しないでください。代わりにStandardErrorから救助してください。それについてはhereを読んでください。

これらのサブクラスでサブクラス固有のエラーのためにrescueを定義すると、その特定のロジックを問題のサブクラスに完全に分離することができます。具体的なエラーキャッチをget_dataメソッドに移動することで、示唆したようにこれを行うことができます。しかし、新しい方法を定義して、非救済方法を使用できるようにすることもできます(デバッグ目的のためだけに、エラーを別の方法で処理したい別のコントローラから)。ここで私はそれをやって検討したい一つの方法です:

class FtpFileReader < FileReader 
    def get_data 
    get_data! 
    rescue Net::FTPPermErro => e 
    # return error message 
    end 

    def get_data! 
    # do stuff 
    end 
end