我是 Ruby 的新手,所以我在理解我遇到的这个奇怪的异常问题时遇到了一些麻烦。我正在使用 ruby-aaws gem 访问 Amazon ECS: 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
抛出 a 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 继承的生成的异常类型。
为了澄清,我有两个问题:
为什么 NameError 是一个 Ruby 内置异常,a
kind_of?(Amazon::AWS::Error)
是一个模块?
答:include Amazon::AWS::Error
我在文件顶部说过,认为它有点像 Java 导入或 C++ 包含。这实际上所做的是将Amazon::AWS::Error
(现在和将来)中定义的所有内容添加到隐式内核类中,该类是每个类的祖先。这意味着任何事情都会过去kind_of?(Amazon::AWS::Error)
。如何最好地将动态创建的异常与
Amazon::AWS::Error
来自其他地方的随机其他异常区分开来?