aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support.rb1
-rw-r--r--activesupport/lib/active_support/backtrace_cleaner.rb72
-rw-r--r--activesupport/lib/active_support/core_ext/exception.rb1
-rw-r--r--activesupport/lib/active_support/test_case.rb10
4 files changed, 82 insertions, 2 deletions
diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb
index d2a7df8bf0..cbfd95f092 100644
--- a/activesupport/lib/active_support.rb
+++ b/activesupport/lib/active_support.rb
@@ -29,6 +29,7 @@ require 'active_support/callbacks'
require 'active_support/core_ext'
require 'active_support/buffered_logger'
+require 'active_support/backtrace_cleaner'
require 'active_support/gzip'
require 'active_support/cache'
diff --git a/activesupport/lib/active_support/backtrace_cleaner.rb b/activesupport/lib/active_support/backtrace_cleaner.rb
new file mode 100644
index 0000000000..0e262c003e
--- /dev/null
+++ b/activesupport/lib/active_support/backtrace_cleaner.rb
@@ -0,0 +1,72 @@
+module ActiveSupport
+ # Many backtraces include too much information that's not relevant for the context. This makes it hard to find the signal
+ # in the backtrace and adds debugging time. With a BacktraceCleaner, you can setup filters and silencers for your particular
+ # context, so only the relevant lines are included.
+ #
+ # If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always
+ # call BacktraceCleaner#remove_silencers!
+ #
+ # Example:
+ #
+ # bc = BacktraceCleaner.new
+ # bc.add_filter { |line| line.gsub(Rails.root, '') }
+ # bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
+ # bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
+ #
+ # Inspired by the Quiet Backtrace gem by Thoughtbot.
+ class BacktraceCleaner
+ def initialize
+ @filters, @silencers = [], []
+ end
+
+ # Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.
+ def clean(backtrace)
+ silence(filter(backtrace))
+ end
+
+ # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
+ #
+ # Example:
+ #
+ # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
+ # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
+ def add_filter(&block)
+ @filters << block
+ end
+
+ # Adds a silencer from the block provided. If the silencer returns true for a given line, it'll be excluded from the
+ # clean backtrace.
+ #
+ # Example:
+ #
+ # # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
+ # backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
+ def add_silencer(&block)
+ @silencers << block
+ end
+
+ # Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as
+ # you suspect a bug in the libraries you use.
+ def remove_silencers!
+ @silencers = []
+ end
+
+
+ private
+ def filter(backtrace)
+ @filters.each do |f|
+ backtrace = backtrace.map { |line| f.call(line) }
+ end
+
+ backtrace
+ end
+
+ def silence(backtrace)
+ @silencers.each do |s|
+ backtrace = backtrace.reject { |line| s.call(line) }
+ end
+
+ backtrace
+ end
+ end
+end
diff --git a/activesupport/lib/active_support/core_ext/exception.rb b/activesupport/lib/active_support/core_ext/exception.rb
index 57c8568334..73470cbe05 100644
--- a/activesupport/lib/active_support/core_ext/exception.rb
+++ b/activesupport/lib/active_support/core_ext/exception.rb
@@ -6,6 +6,7 @@ module ActiveSupport
end
end
+# TODO: Turn all this into using the BacktraceCleaner.
class Exception # :nodoc:
def clean_message
Pathname.clean_within message
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index 5b825b212d..d1e657c15f 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -21,15 +21,21 @@ module ActiveSupport
Assertion = MiniTest::Assertion
end
+ # TODO: Figure out how to get the Rails::BacktraceFilter into minitest/unit
# Test::Unit compatibility.
rescue LoadError
require 'test/unit/testcase'
require 'active_support/testing/default'
+ if defined?(Rails)
+ require 'rails/backtrace_cleaner'
+ Test::Unit::Util::BacktraceFilter.module_eval { include Rails::BacktraceFilterForTestUnit }
+ end
+
class TestCase < ::Test::Unit::TestCase
Assertion = Test::Unit::AssertionFailedError
include ActiveSupport::Testing::Default
- end
+ end
end
class TestCase
@@ -37,4 +43,4 @@ module ActiveSupport
include ActiveSupport::Testing::Assertions
extend ActiveSupport::Testing::Declarative
end
-end
+end \ No newline at end of file