diff options
author | tyler-ball <tyleraball@gmail.com> | 2014-10-31 07:05:21 -0700 |
---|---|---|
committer | tyler-ball <tyleraball@gmail.com> | 2014-12-17 18:47:25 -0800 |
commit | 390b858f2cfb130817573813294cb77b84f71874 (patch) | |
tree | e6e1f56bf2911bc7b40516b21cc5df88442f776f | |
parent | 66665a7f699a592b77249a31af229f1412d90458 (diff) | |
download | chef-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.rb | 16 | ||||
-rw-r--r-- | lib/chef/dsl/audit.rb | 2 | ||||
-rw-r--r-- | lib/chef/exceptions.rb | 11 | ||||
-rw-r--r-- | spec/unit/exceptions_spec.rb | 46 |
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 |