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 saidinclude Amazon::AWS::Error
at 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 inAmazon::AWS::Error
(present and future) to the implicit Kernel class, which is an ancestor of every class. This means anything would passkind_of?(Amazon::AWS::Error)
.How can I best distinguish the dynamically-created exceptions in
Amazon::AWS::Error
from random other exceptions from elsewhere?