diff --git a/features/cli/debug.feature b/features/cli/debug.feature index 74bdb46..2d6f25c 100644 --- a/features/cli/debug.feature +++ b/features/cli/debug.feature @@ -1,11 +1,13 @@ Feature: CLI debug option - Background: - Given a recipe with: - """ - task(:trigger_error) { fail 'some error' } - """ - - Scenario: reports recipe errors + Scenario: reports recipe errors with their cause + Given a recipe with an error When I execute the recipe with option -d Then the output must match /\ARuntimeError:.*\n\ncause:\nRuntimeError:/ + + Scenario: does not exclude anything from backtrace + Given a recipe using a remote + When I execute the recipe on unknown remote target with option -d + Then the output must contain "producer-core" + And the output must contain "net-ssh" + And the output must contain ruby lib directory diff --git a/features/steps/output_steps.rb b/features/steps/output_steps.rb index ea1630c..ec15996 100644 --- a/features/steps/output_steps.rb +++ b/features/steps/output_steps.rb @@ -26,6 +26,10 @@ Then /^the error output must contain exactly "([^"]+)"$/ do |content| assert_exact_output content, all_stderr end +Then /^the output must contain ruby lib directory$/ do + assert_partial_output RbConfig::CONFIG['rubylibdir'], all_output +end + Then /^the output must not contain ruby lib directory$/ do assert_no_partial_output RbConfig::CONFIG['rubylibdir'], all_output end diff --git a/features/steps/recipe_steps.rb b/features/steps/recipe_steps.rb index 93ed953..40b703b 100644 --- a/features/steps/recipe_steps.rb +++ b/features/steps/recipe_steps.rb @@ -27,6 +27,11 @@ When /^I execute the recipe on unknown remote target$/ do assert_matching_output '\ASocketError', all_output end +When /^I execute the recipe on unknown remote target with option (-.+)$/ do |option| + run_simple "producer recipe.rb #{option} -t #unknown_host.test", false + assert_matching_output '\ASocketError', all_output +end + When /^I successfully execute the recipe$/ do step 'I execute the recipe' assert_exit_status 0 diff --git a/lib/producer/core/error_formatter.rb b/lib/producer/core/error_formatter.rb index ceadfe5..91b7c9e 100644 --- a/lib/producer/core/error_formatter.rb +++ b/lib/producer/core/error_formatter.rb @@ -18,7 +18,7 @@ module Producer end def format(exception) - lines = format_exception exception + lines = format_exception exception, filter: !debug? if debug? && exception.cause lines << '' diff --git a/spec/producer/core/error_formatter_spec.rb b/spec/producer/core/error_formatter_spec.rb index ff8576b..3fbe932 100644 --- a/spec/producer/core/error_formatter_spec.rb +++ b/spec/producer/core/error_formatter_spec.rb @@ -25,9 +25,10 @@ module Producer describe '#format' do let(:rubylibdir) { RbConfig::CONFIG['rubylibdir'] } let(:bt) { %W[backtrace /producer-core /net-ssh #{rubylibdir}] } + let(:exception) { RuntimeError.new('some exception').tap { |o| o.set_backtrace bt } } - def exception - begin fail 'original exception' rescue fail 'some exception' end + def exception_with_cause + begin fail 'exception cause' rescue fail 'some exception' end rescue => e e.tap { |o| o.set_backtrace bt } end @@ -41,24 +42,41 @@ module Producer expect(formatter.format exception).to match /^\s+backtrace$/ end - context 'filtering' do - it 'excludes producer code from the backtrace' do - expect(formatter.format exception).not_to include 'producer-core' + it 'excludes producer code from the backtrace' do + expect(formatter.format exception).not_to include 'producer-core' + end + + it 'excludes net-ssh from the backtrace' do + expect(formatter.format exception).not_to include 'net-ssh' + end + + it 'excludes ruby lib directory from the backtrace' do + expect(formatter.format exception).not_to include rubylibdir + end + + context 'when exception has a cause' do + it 'does not include the cause' do + expect(formatter.format exception_with_cause) + .not_to include 'exception cause' + end + end + + context 'when debug is enabled' do + let(:debug) { true } + + it 'does not filter the backtrace' do + expect(formatter.format exception).to include 'producer-core' end - it 'excludes net-ssh from the backtrace' do - expect(formatter.format exception).not_to include 'net-ssh' - end + context 'when exception has a cause' do + it 'includes the exception cause' do + expect(formatter.format exception_with_cause) + .to include 'exception cause' + end - it 'excludes ruby lib directory from the backtrace' do - expect(formatter.format exception).not_to include rubylibdir - end - - context 'when debug is enabled' do - let(:debug) { true } - - it 'does not exclude producer code from the backtrace' do - expect(formatter.format exception).to include 'producer-core' + it 'formats the cause' do + expect(formatter.format exception_with_cause) + .to match /^cause:\nRuntimeError: exception cause/ end end end