diff options
-rw-r--r-- | lib/chef/dsl/recipe.rb | 25 | ||||
-rw-r--r-- | lib/chef/exceptions.rb | 4 | ||||
-rw-r--r-- | lib/chef/resource_platform_map.rb | 2 | ||||
-rw-r--r-- | spec/unit/recipe_spec.rb | 27 |
4 files changed, 55 insertions, 3 deletions
diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index a1bdd9d665..d8d0b158b3 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -51,10 +51,16 @@ class Chef # to. if has_resource_definition?(method_symbol) evaluate_resource_definition(method_symbol, *args, &block) - else + elsif have_resource_class_for?(method_symbol) # Otherwise, we're rocking the regular resource call route. declare_resource(method_symbol, args[0], caller[0], &block) + else + super end + rescue NoMethodError + raise NoMethodError, "No resource or method named `#{method_symbol}' for #{describe_self_for_error}" + rescue NameError + raise NameError, "No resource, method, or local variable named `#{method_symbol}' for #{describe_self_for_error}" end def has_resource_definition?(name) @@ -107,7 +113,6 @@ class Chef # backward compatibility resource_class = resource_class_for(type) - super unless resource_class raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? resource = resource_class.new(name, run_context) @@ -138,6 +143,22 @@ class Chef Chef::Resource.resource_for_node(snake_case_name, run_context.node) end + def have_resource_class_for?(snake_case_name) + not resource_class_for(snake_case_name).nil? + rescue NameError + false + end + + def describe_self_for_error + if respond_to?(:name) + %Q[`#{self.class.name} "#{name}"'] + elsif respond_to?(:recipe_name) + %Q[`#{self.class.name} "#{recipe_name}"'] + else + to_s + end + end + end end end diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb index 0b4cd28d03..afd42885f9 100644 --- a/lib/chef/exceptions.rb +++ b/lib/chef/exceptions.rb @@ -80,6 +80,10 @@ class Chef class ConflictingMembersInGroup < ArgumentError; end class InvalidResourceReference < RuntimeError; end class ResourceNotFound < RuntimeError; end + + # Can't find a Resource of this type that is valid on this platform. + class NoSuchResourceType < NameError; end + class InvalidResourceSpecification < ArgumentError; end class SolrConnectionError < RuntimeError; end class IllegalChecksumRevert < RuntimeError; end diff --git a/lib/chef/resource_platform_map.rb b/lib/chef/resource_platform_map.rb index ad27aa91c1..a678f5be4b 100644 --- a/lib/chef/resource_platform_map.rb +++ b/lib/chef/resource_platform_map.rb @@ -123,7 +123,7 @@ class Chef resource_klass = platform_resource(short_name, platform, version) || resource_matching_short_name(short_name) - raise NameError, "Cannot find a resource for #{short_name} on #{platform} version #{version}" if resource_klass.nil? + raise Exceptions::NoSuchResourceType, "Cannot find a resource for #{short_name} on #{platform} version #{version}" if resource_klass.nil? resource_klass end diff --git a/spec/unit/recipe_spec.rb b/spec/unit/recipe_spec.rb index bc3a62be3f..612eae2b8e 100644 --- a/spec/unit/recipe_spec.rb +++ b/spec/unit/recipe_spec.rb @@ -175,6 +175,33 @@ describe Chef::Recipe do end + describe "when attempting to create a resource of an invalid type" do + + it "gives a sane error message when using method_missing" do + lambda do + @recipe.no_such_resource("foo") + end.should raise_error(NoMethodError, %q[No resource or method named `no_such_resource' for `Chef::Recipe "test"']) + end + + it "gives a sane error message when using method_missing 'bare'" do + lambda do + @recipe.instance_eval do + # Giving an argument will change this from NameError to NoMethodError + no_such_resource + end + end.should raise_error(NameError, %q[No resource, method, or local variable named `no_such_resource' for `Chef::Recipe "test"']) + end + + it "gives a sane error message when using build_resource" do + expect { @recipe.build_resource(:no_such_resource, "foo") }.to raise_error(Chef::Exceptions::NoSuchResourceType) + end + + it "gives a sane error message when using declare_resource" do + expect { @recipe.declare_resource(:no_such_resource, "bar") }.to raise_error(Chef::Exceptions::NoSuchResourceType) + end + + end + describe "resource definitions" do it "should execute defined resources" do crow_define = Chef::ResourceDefinition.new |