Module: AWS::Core::LazyErrorClasses

Overview

Provides lazy creation of error classes via #const_missing.

Extend this module provides 3 benefits to another module:

  • A method that accepts strings and returns error classes.

  • Thread-safe dynamic error class creation via #const_missing

  • An error grammar for parsing AWS xml errors

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 Errors::Base.

Constant Summary collapse

BASE_ERROR_GRAMMAR =

This grammar parses the defualt AWS XML error format

XML::Grammar.customize do
  element("Error") do
    ignore
  end
end

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object


54
55
56
57
58
59
60
61
62
63
# 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

Instance Method Details

#const_missing(constant) ⇒ nil

Defines a new error class.

Parameters:

  • constant (String, Symbol)

Returns:

  • (nil)

68
69
70
71
72
# File 'lib/aws/core/lazy_error_classes.rb', line 68

def const_missing constant
  const_missing_mutex.synchronize do
    const_set(constant, Class.new(Errors::Base) { extend LazyErrorClasses })
  end
end

#error_class(code) ⇒ Class

Converts the error code into an error class constant.

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

Parameters:

  • code (String)

    An AWS error code.

Returns:

  • (Class)

    Returns the error class defiend by the error code.


83
84
85
# File 'lib/aws/core/lazy_error_classes.rb', line 83

def error_class code
  module_eval("#{self}::#{code.gsub('.Range','Range').gsub(".","::")}")
end