【发布时间】:2010-09-09 08:43:05
【问题描述】:
我是 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 抛出 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 内置异常,一个
kind_of?(Amazon::AWS::Error),它是一个模块?
答案:我在文件顶部说过include Amazon::AWS::Error,认为它有点像 Java 导入或 C++ 包含。这实际上所做的是将Amazon::AWS::Error(现在和未来)中定义的所有内容添加到隐式内核类,它是每个类的祖先。这意味着 anything 将通过kind_of?(Amazon::AWS::Error)。如何最好地将
Amazon::AWS::Error中动态创建的异常与其他地方的随机其他异常区分开来?
【问题讨论】:
-
很难理解您的问题,因为类型 Amazon::AWS::Error 似乎与您在问题顶部提供的源代码无关。可能是粘贴错误?
-
糟糕,我忘记了“AWS”模块。我剪掉了文件中很多不相关的部分,我一定会错过它。所以我们有一个 Amazon 模块,然后是一个 AWS 模块,然后是一个 Error 模块,然后是一个 AWSError 类,它在 Amazon::AWS::Error 模块中设置常量。
标签: ruby exception metaprogramming