summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb26
-rw-r--r--spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb40
2 files changed, 61 insertions, 5 deletions
diff --git a/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb b/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb
index 5642070336..cfee8a2151 100644
--- a/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb
+++ b/lib/chef/formatters/error_inspectors/cookbook_resolve_error_inspector.rb
@@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -80,6 +80,9 @@ E
def describe_412_error(error_description)
explanation = ""
error_reasons = extract_412_error_message
+
+ # Prepare the error message if there is detailed information
+ # about individual cookbooks.
if !error_reasons.respond_to?(:key?)
explanation << error_reasons.to_s
else
@@ -99,7 +102,24 @@ E
end
end
- error_description.section("Missing Cookbooks:", explanation)
+ if !explanation.empty?
+ error_description.section("Missing Cookbooks:", explanation)
+ else
+ # If we don't have any cookbook details print a more
+ # generic error message.
+ if error_reasons.respond_to?(:key?) && error_reasons["message"]
+ explanation << "Error message: #{error_reasons["message"]}\n"
+ end
+
+ explanation << <<EOM
+You might be able to resolve this issue with:
+ 1-) Removing cookbook versions that depend on deleted cookbooks.
+ 2-) Removing unused cookbook versions.
+ 3-) Pinning exact cookbook versions using environments.
+EOM
+ error_description.section("Cookbook dependency resolution error:", explanation)
+ end
+
error_description.section("Expanded Run List:", expanded_run_list_ul)
end
diff --git a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
index bb694f8e5c..cf668fbb0d 100644
--- a/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
+++ b/spec/unit/formatters/error_inspectors/cookbook_resolve_error_inspector_spec.rb
@@ -24,8 +24,9 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
@expanded_run_list = Chef::RunList.new("recipe[annoyances]", "recipe[apache2]", "recipe[users]", "recipe[chef::client]")
@description = Chef::Formatters::ErrorDescription.new("Error Resolving Cookbooks for Run List:")
- @outputter = Chef::Formatters::Outputter.new(StringIO.new, STDERR)
- #@outputter = Chef::Formatters::Outputter.new(STDOUT, STDERR)
+ @outputter_output = StringIO.new
+ @outputter = Chef::Formatters::Outputter.new(@outputter_output, STDERR)
+ # @outputter = Chef::Formatters::Outputter.new(STDOUT, STDERR)
end
describe "when explaining a 403 error" do
@@ -63,6 +64,36 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
it "prints a pretty message" do
@description.display(@outputter)
+ @outputter_output.rewind
+ observed_output = @outputter_output.read
+ observed_output.should include("apache2")
+ observed_output.should include("users")
+ observed_output.should_not include("Run list contains invalid items: no such cookbook nope.")
+ end
+
+ end
+
+ describe "when explaining a PreconditionFailed (412) error with current error message style without cookbook details" do
+ # Chef currently returns error messages with some fields as JSON strings,
+ # which must be re-parsed to get the actual data.
+ # In some cases the error message doesn't contain any cookbook
+ # details. But we should still print a pretty error message.
+
+ before do
+
+ @response_body = "{\"error\":[{\"non_existent_cookbooks\":[],\"cookbooks_with_no_versions\":[],\"message\":\"unable to solve dependencies in alotted time.\"}]}"
+ @response = Net::HTTPPreconditionFailed.new("1.1", "412", "(response) unauthorized")
+ @response.stub!(:body).and_return(@response_body)
+ @exception = Net::HTTPServerException.new("(exception) precondition failed", @response)
+
+ @inspector = Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector.new(@expanded_run_list, @exception)
+ @inspector.add_explanation(@description)
+ end
+
+ it "prints a pretty message" do
+ @description.display(@outputter)
+ @outputter_output.rewind
+ @outputter_output.read.should include("unable to solve dependencies in alotted time.")
end
end
@@ -84,6 +115,11 @@ describe Chef::Formatters::ErrorInspectors::CookbookResolveErrorInspector do
it "prints a pretty message" do
@description.display(@outputter)
+ @outputter_output.rewind
+ observed_output = @outputter_output.read
+ observed_output.should include("apache2")
+ observed_output.should include("users")
+ observed_output.should_not include("Run list contains invalid items: no such cookbook nope.")
end
end