I'm new to Ruby, so I'm having some trouble understanding this weird exception problem I'm having. I'm using the ruby-aaws gem to access Amazon ECS: http://www.caliban.org/ruby/ruby-aws/. This defines a class 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
This means that if you get an errorcode like AWS.InvalidParameterValue, this will produce (in its exception variable) a new class Amazon::AWS::Error::InvalidParameterValue which is a subclass of StandardError.
Now here's where it gets weird. I have some code that looks like this:
begin
  do_aws_stuff
rescue Amazon::AWS::Error => error
  puts "Got an AWS error"
end
Now, if do_aws_stuff throws a NameError, my rescue block gets triggered. It seems that Amazon::AWS::Error isn't the superclass of the generated error - I guess since it's a module everything is a subclass of it? Certainly if I do:
irb(main):007:0> NameError.new.kind_of?(Amazon::AWS::Error)
=> true
It says true, which I find confusing, especially given this:
irb(main):009:0> NameError.new.kind_of?(Amazon::AWS)
=> false
What's going on, and how am I supposed to separate out AWS errors from other type of errors? Should I do something like:
begin
  do_aws_stuff
rescue => error
  if error.class.to_s =~ /^Amazon::AWS::Error/
    puts "Got an AWS error"
  else
    raise error
  end
end
That seems exceptionally janky. The errors thrown aren't class AWSError either - they're raised like this:
error = Amazon::AWS::Error::AWSError.new( xml )
raise error.exception
So the exceptions I'm looking to rescue from are the generated exception types that only inherit from StandardError.
To clarify, I have two questions:
- Why is NameError, a Ruby built in exception, a - kind_of?(Amazon::AWS::Error), which is a module?
 Answer: I had said- include Amazon::AWS::Errorat the top of my file, thinking it was kind of like a Java import or C++ include. What this actually did was add everything defined in- Amazon::AWS::Error(present and future) to the implicit Kernel class, which is an ancestor of every class. This means anything would pass- kind_of?(Amazon::AWS::Error).
- How can I best distinguish the dynamically-created exceptions in - Amazon::AWS::Errorfrom random other exceptions from elsewhere?