summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortyler-ball <tyleraball@gmail.com>2014-10-31 07:05:21 -0700
committertyler-ball <tyleraball@gmail.com>2014-12-17 18:47:25 -0800
commit390b858f2cfb130817573813294cb77b84f71874 (patch)
treee6e1f56bf2911bc7b40516b21cc5df88442f776f
parent66665a7f699a592b77249a31af229f1412d90458 (diff)
downloadchef-390b858f2cfb130817573813294cb77b84f71874.tar.gz
Adding error handling so saving node doesn't prevent us from running audit mode - decouples converge phase and audit phase more
-rw-r--r--lib/chef/client.rb16
-rw-r--r--lib/chef/dsl/audit.rb2
-rw-r--r--lib/chef/exceptions.rb11
-rw-r--r--spec/unit/exceptions_spec.rb46
4 files changed, 69 insertions, 6 deletions
diff --git a/lib/chef/client.rb b/lib/chef/client.rb
index b41db70689..6c83639ec3 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -326,6 +326,19 @@ class Chef
converge_exception
end
+ # TODO don't want to change old API
+ def converge_and_save(run_context)
+ converge_exception = converge(run_context)
+ unless converge_exception
+ begin
+ save_updated_node
+ rescue Exception => e
+ converge_exception = e
+ end
+ end
+ converge_exception
+ end
+
# TODO are failed audits going to raise exceptions, or only be handled by the reporters?
def run_audits(run_context)
audit_exception = nil
@@ -414,8 +427,7 @@ class Chef
run_context = setup_run_context
- converge_error = converge(run_context)
- save_updated_node unless converge_error
+ converge_error = converge_and_save(run_context)
audit_error = run_audits(run_context)
if converge_error || audit_error
diff --git a/lib/chef/dsl/audit.rb b/lib/chef/dsl/audit.rb
index fee89c02ca..7adcecbf14 100644
--- a/lib/chef/dsl/audit.rb
+++ b/lib/chef/dsl/audit.rb
@@ -24,7 +24,7 @@ class Chef
# Adds the controls group and block (containing controls to execute) to the runner's list of pending examples
def controls(group_name, &group_block)
- raise ::Chef::Exceptions::NoAuditsProvided("You must provide a block with audits") unless group_block
+ raise ::Chef::Exceptions::NoAuditsProvided unless group_block
# TODO add the @example_groups list to the runner for later execution
# run_context.audit_runner.register
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 179a1fa27e..842910f2ae 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -385,7 +385,11 @@ class Chef
end
end
- class NoAuditsProvided < RuntimeError; end
+ class NoAuditsProvided < RuntimeError
+ def initialize
+ super "You must provide a block with audits"
+ end
+ end
# If a converge or audit fails, we want to wrap the output from those errors into 1 error so we can
# see both issues in the output. It is possible that nil will be provided. You must call `fill_backtrace`
@@ -402,10 +406,11 @@ class Chef
def fill_backtrace
backtrace = []
wrapped_errors.each_with_index do |e,i|
- backtrace << "#{i+1}) #{e.message}"
- backtrace += e.backtrace
+ backtrace << "#{i+1}) #{e.class} - #{e.message}"
+ backtrace += e.backtrace if e.backtrace
backtrace << ""
end
+ set_backtrace(backtrace)
end
end
end
diff --git a/spec/unit/exceptions_spec.rb b/spec/unit/exceptions_spec.rb
index 6318ec9227..165c11446b 100644
--- a/spec/unit/exceptions_spec.rb
+++ b/spec/unit/exceptions_spec.rb
@@ -81,4 +81,50 @@ describe Chef::Exceptions do
end
end
end
+
+ describe Chef::Exceptions::RunFailedWrappingError do
+ shared_examples "RunFailedWrappingError expectations" do
+ it "should initialize with a default message" do
+ expect(e.message).to eq("Found #{num_errors} errors, they are stored in the backtrace\n")
+ end
+
+ it "should provide a modified backtrace when requested" do
+ e.fill_backtrace
+ expect(e.backtrace).to eq(backtrace)
+ end
+ end
+
+ context "initialized with nothing" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new }
+ let(:num_errors) { 0 }
+ let(:backtrace) { [] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with nil" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(nil, nil) }
+ let(:num_errors) { 0 }
+ let(:backtrace) { [] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with 1 error and nil" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(RuntimeError.new("foo"), nil) }
+ let(:num_errors) { 1 }
+ let(:backtrace) { ["1) RuntimeError - foo", ""] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ context "initialized with 2 errors" do
+ let(:e) { Chef::Exceptions::RunFailedWrappingError.new(RuntimeError.new("foo"), RuntimeError.new("bar")) }
+ let(:num_errors) { 2 }
+ let(:backtrace) { ["1) RuntimeError - foo", "", "2) RuntimeError - bar", ""] }
+
+ include_examples "RunFailedWrappingError expectations"
+ end
+
+ end
end