私はRubyを初めて使用するため、この奇妙な例外の問題を理解するのに苦労しています。私はruby-aawsgemを使用してAmazonECSにアクセスしています:http://www.caliban.org/ruby/ruby-aws/。これにより、クラスAmazon :: AWS:Error:が定義されます。
module Amazon
module AWS
# All dynamically generated exceptions occur within this namespace.
#
module Error
# An exception generator class.
#
class AWSError
attr_reader :exception
def initialize(xml)
err_class = xml.elements['Code'].text.sub( /^AWS.*\./, '' )
err_msg = xml.elements['Message'].text
unless Amazon::AWS::Error.const_defined?( err_class )
Amazon::AWS::Error.const_set( err_class,
Class.new( StandardError ) )
end
ex_class = Amazon::AWS::Error.const_get( err_class )
@exception = ex_class.new( err_msg )
end
end
end
end
end
これは、のようなエラーコードを取得した場合、AWS.InvalidParameterValue
(例外変数で)Amazon::AWS::Error::InvalidParameterValue
のサブクラスである新しいクラスを生成することを意味しますStandardError
。
今ここでそれは奇妙になります。私はこのように見えるいくつかのコードを持っています:
begin
do_aws_stuff
rescue Amazon::AWS::Error => error
puts "Got an AWS error"
end
ここで、do_aws_stuff
をスローするNameError
と、レスキューブロックがトリガーされます。Amazon :: AWS :: Errorは、生成されたエラーのスーパークラスではないようです-モジュールなので、すべてがそのサブクラスだと思いますか?確かに私がそうするなら:
irb(main):007:0> NameError.new.kind_of?(Amazon::AWS::Error)
=> true
それはtrue
、特にこれを考えると、私が混乱していると思うと言います:
irb(main):009:0> NameError.new.kind_of?(Amazon::AWS)
=> false
何が起こっているのでしょうか。また、AWSエラーを他のタイプのエラーからどのように分離する必要がありますか?私は次のようなことをする必要があります:
begin
do_aws_stuff
rescue => error
if error.class.to_s =~ /^Amazon::AWS::Error/
puts "Got an AWS error"
else
raise error
end
end
それは非常にぎこちないようです。スローされるエラーもクラスAWSErrorではありません-次のように発生します:
error = Amazon::AWS::Error::AWSError.new( xml )
raise error.exception
したがって、私が探している例外rescue
は、StandardErrorからのみ継承する生成された例外タイプです。
明確にするために、2つの質問があります。
Rubyに組み込まれている例外であるNameErrorが
kind_of?(Amazon::AWS::Error)
モジュールであるのはなぜですか?
回答:include Amazon::AWS::Error
ファイルの先頭で、JavaインポートやC++インクルードのようなものだと思っていました。これが実際に行ったことは、Amazon::AWS::Error
(現在および将来)で定義されたすべてのものを、すべてのクラスの祖先である暗黙のKernelクラスに追加することでした。これは、何でも合格することを意味しkind_of?(Amazon::AWS::Error)
ます。Amazon::AWS::Error
動的に作成された例外を他の場所からのランダムな他の例外と最もよく区別するにはどうすればよいですか?