From a96fdcfabb15f2a46f7fda1dc4386c2f964595a3 Mon Sep 17 00:00:00 2001 From: Simon Coffey Date: Mon, 16 Oct 2017 16:52:32 +0100 Subject: [PATCH] Clarify output when printing nested exception traces Since v12.1.0, if an exception has a nested cause exception, the cause is also displayed in the trace output.[1] For heavily-nested exceptions, this output can be quite lengthy - for example, Rails migrations nest DB errors twice over, resulting in an error message and backtrace repeated three times. To break up this output and make it clearer what each individual backtrace relates to, this adds whitespace and a "Caused by:" label to each nested exception being displayed. To prevent "Caused by:" labels occurring on their own, I've moved the exception loop shortcut return into the `#display_cause_details` method. This doesn't alter the behaviour of the shortcut, as only the first exception will be unconditionally printed (which was already the case, as the first exception can't be already seen). [1] https://github.com/ruby/rake/commit/fbb22e7f570fc573ad1bff9d5905df1ab1cbd475 [2] https://github.com/ruby/rake/commit/57c932cea12ef3201fcaeaf80ba6f4f545390269 --- lib/rake/application.rb | 17 +++++++++++++---- test/test_rake_application.rb | 1 + 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/rake/application.rb b/lib/rake/application.rb index 89565a670..8420a942b 100644 --- a/lib/rake/application.rb +++ b/lib/rake/application.rb @@ -207,13 +207,22 @@ def display_error_message(ex) # :nodoc: end def display_exception_details(ex) # :nodoc: - seen = Thread.current[:rake_display_exception_details_seen] ||= [] - return if seen.include? ex - seen << ex + display_exception_details_seen << ex display_exception_message_details(ex) display_exception_backtrace(ex) - display_exception_details(ex.cause) if has_cause?(ex) + display_cause_details(ex.cause) if has_cause?(ex) + end + + def display_cause_details(ex) # :nodoc: + return if display_exception_details_seen.include? ex + + trace "\nCaused by:" + display_exception_details(ex) + end + + def display_exception_details_seen + Thread.current[:rake_display_exception_details_seen] ||= [] end def has_cause?(ex) # :nodoc: diff --git a/test/test_rake_application.rb b/test/test_rake_application.rb index cc063c0d2..d17445c7e 100644 --- a/test/test_rake_application.rb +++ b/test/test_rake_application.rb @@ -97,6 +97,7 @@ def test_display_exception_details_cause assert_empty out + assert_match "Caused by:", err assert_match "cause a", err assert_match "cause b", err end