我是新来的宝石,所以我有些麻烦了解这个奇怪的异常问题,我有。我使用的是红宝石的aaws宝石访问亚马逊ECS: http://www.caliban.org/ruby/ruby-aws/.这样限定了一类Amazon::您错误:

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

这意味着,如果你得到一个errorcode喜欢 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, 我救块被触发。看来,亚马逊::您:误差不超类的产生错误的-我猜因为它是一个模块的一切是一个子类的吗?当然,如果我这样做:

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.

为了澄清,我有两个问题:

  1. 为什么是NameError,红宝石建成的异常, kind_of?(Amazon::AWS::Error), ,这是一个模块?
    回答: 我不得不说 include Amazon::AWS::Error 在我的文件,认为它是一种喜欢一个Java进口或C++包括。这实际上做的是添加一切定义 Amazon::AWS::Error (现在和将来),以隐含的核心类,这是一个祖先的每一类。这意味着 任何东西 将通过 kind_of?(Amazon::AWS::Error).

  2. 我可以如何最佳区分的动态创建的例外情况 Amazon::AWS::Error 从随机的其他例外情况,从其他地方?

有帮助吗?

解决方案

好吧,我会尽力帮助在这里:

第一个模块是不是一类的,它可以让你混合行为中的一类。第二个看以下例子:

module A
  module B
    module Error
      def foobar
        puts "foo"
      end
    end
  end
end

class StandardError
  include A::B::Error
end

StandardError.new.kind_of?(A::B::Error)
StandardError.new.kind_of?(A::B)
StandardError.included_modules #=> [A::B::Error,Kernel]

kind_of?告诉你,是的,错误不会拥有所有的:B::错误的行为(这是正常的,因为它包括:B::错误)然而其中不包括所有行为,从A::B和因此不是一个:B。(鸭打字)

现在有一个很好的机会,红宝石有关信息请参阅重新开放一个超类的NameError和包括Amazon::您错在那里。(猴子的修补)

你可以找出通过程序里的模块包含的层次结构如下:

class Class
  def has_module?(module_ref)
    if self.included_modules.include?(module_ref) and not self.superclass.included_modules.include?(module_ref)                      
        puts self.name+" has module "+ module_ref.name          
    else
      self.superclass.nil? ? false : self.superclass.has_module?(module_ref)
    end        
  end
end
StandardError.has_module?(A::B::Error)
NameError.has_module?(A::B::Error)

关于你的的第二个问题,我看不到任何东西比

begin 
#do AWS error prone stuff
rescue Exception => e
  if Amazon::AWS::Error.constants.include?(e.class.name)
    #awsError
  else
    whatever
  end 
end

(编辑上的代码不工作是:名字包括模块的前缀它不是这种情况的常量阵列。你肯定应该接触lib维护者的AWSError类看起来更像是一个厂类对我说:/)

我没有红宝石的有关信息请参阅在这里和卡利班网站被封锁的公司的防火墙,所以我不能测试更进一步。

关于包括:可能的事情做猴子补上StandardError层次结构。我不知道了,但最有可能这样做的根本文件之外的每一个方面是包括模块上的象或对象上元类.(这是什么会发生在移民和难民委员会,在那里默认的上下文是目的,不肯定的关于在文件)

镐上模块 :

A couple of points about the include statement before we go on. First, it has nothing to do with files. C programmers use a preprocessor directive called #include to insert the contents of one file into another during compilation. The Ruby include statement simply makes a reference to a named module. If that module is in a separate file, you must use require to drag that file in before using include.

(编辑-我不能似乎是能够使用浏览器:/耶锁定在平台)

其他提示

好吧,从我可以告诉:

Class.new( StandardError )

是创建一个新的类StandardError为基类,所以它不是一个Amazon::您:错误的。这只是定义中的模块,这可能是为什么它是一个kind_of?Amazon::您:错误。它可能不是一个kind_of?Amazon:资,因为可能的模块不巢的目的kind_of??

对不起,我不知道模块很好的红宝石,但最肯定的基类将是StandardError.

更新:通过这种方式, 从红宝石文件:

obj。kind_of?(class)=>真正的或虚假的

Returns true if类的obj,或者如果类是一个超类的obj或模块包括在obj。

只是想报:我同意这是一个错误的lib代码。它也许应该读作:

      unless Amazon::AWS::Error.const_defined?( err_class )
        kls = Class.new( StandardError )
        Amazon::AWS::Error.const_set(err_class, kls)
        kls.include Amazon::AWS::Error
      end

一个问题你遇到的是, Amazon::AWS::Error::AWSError 实际上不是一个例外。时 raise 是所谓的,这看起来看,如果第一个参数作出响应的 exception 方法和将使用的结果,而不是。任何一个亚类的 Exception 将返回自己的时候 exception 是所谓的,你可以做的事情一样 raise Exception.new("Something is wrong").

在这种情况下, AWSErrorexception 设置作为一个属性读者其它值定义,在初始化之类的东西 Amazon::AWS::Error::SOME_ERROR.这意味着,当你打电话 raise Amazon::AWS::Error::AWSError.new(SOME_XML) Ruby结束了 Amazon::AWS::Error::AWSError.new(SOME_XML).exception 这将返回的一个实例 Amazon::AWS::Error::SOME_ERROR.正如所指出的另一反应者,此类是直接的子 StandardError 而不是被一个子类的共同亚马逊的错误。直到这是纠正,让的解决方案可能是你最好的选择。

我希望,帮助解释更多的是怎么在幕后。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top