module AWS::Core::LazyErrorClasses

Provides lazy creation of error classes via {#const_missing}.

Extend this module provides 3 benefits to another module:

Here is an example of how it works:

Class Foo
  module Errors
    extend AWS::Core::LazyErrorClasses
  end
end

Foo::Errors.error_class('NoSuchKey')
#=> Foo::Errors::NoSuckKey

Foo::Errors.error_class('Nested.Error.Klasses')
#=> Foo::Errors::Nested::Error::Klasses

The errors returned from {#error_class} are subclasses of {AWS::Errors::Base}.

Constants

BASE_ERROR_GRAMMAR

This grammar parses the defualt AWS XML error format

Public Class Methods

extended(base) click to toggle source

@api private

# File lib/aws/core/lazy_error_classes.rb, line 54
def self.extended base

  unless base.const_defined?(:GRAMMAR)
    base.const_set(:GRAMMAR, BASE_ERROR_GRAMMAR)
  end

  mutex = Mutex.new
  MetaUtils.extend_method(base, :const_missing_mutex) { mutex }

end

Public Instance Methods

const_missing(constant) click to toggle source

Defines a new error class. @param [String,Symbol] constant @return [nil]

# File lib/aws/core/lazy_error_classes.rb, line 68
def const_missing constant
  const_missing_mutex.synchronize do
    # It's possible the constant was defined by another thread while
    # this thread was waiting on the mutex, check before setting.
    if error_const_set?(constant)
      const_get(constant)
    else
      const_set(constant, Class.new(Errors::Base) { extend LazyErrorClasses })
    end
  end
end
error_class(code) click to toggle source

Converts the error code into an error class constant.

AWS::EC2::Errors.error_class('Non.Existent.Error')
#=> AWS::EC2::Errors::Non::Existent::Error

@param [String] code An AWS error code.

@return [Class] Returns the error class defiend by the error code.

# File lib/aws/core/lazy_error_classes.rb, line 89
def error_class code
  module_eval("#{self}::#{code.gsub('.Range','Range').gsub(".","::")}")
end

Private Instance Methods

error_const_set?(constant) click to toggle source

@return [Boolean] Returns true if the constant is defined in the

current module.
# File lib/aws/core/lazy_error_classes.rb, line 97
def error_const_set?(constant)
  # Not using #const_defined? because in Ruby 1.9+, it returns true for
  # constants not defined directly on the current module.
  constant = constant.to_sym
  # In Ruby 1.8, #constants returns an array of strings,
  # in Ruby 1.9+, #constants returns an array of symbols.
  constants.any? { |c| c.to_sym == constant }
end