aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/backtrace_cleaner.rb
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2008-11-22 18:06:08 +0100
committerDavid Heinemeier Hansson <david@loudthinking.com>2008-11-22 18:06:08 +0100
commitf42c77f927eb49b00e84d355e07de48723d03fcb (patch)
tree2a459814a9708f292c99e9c5e99dd41d2d801353 /activesupport/lib/active_support/backtrace_cleaner.rb
parenta026b4c983681b71d876ea37958c3e5bc605acac (diff)
downloadrails-f42c77f927eb49b00e84d355e07de48723d03fcb.tar.gz
rails-f42c77f927eb49b00e84d355e07de48723d03fcb.tar.bz2
rails-f42c77f927eb49b00e84d355e07de48723d03fcb.zip
Added ActiveSupport::BacktraceCleaner and Rails::BacktraceCleaner for cutting down on backtrace noise (inspired by the Thoughtbot Quiet Backtrace plugin) [DHH]
Diffstat (limited to 'activesupport/lib/active_support/backtrace_cleaner.rb')
-rw-r--r--activesupport/lib/active_support/backtrace_cleaner.rb72
1 files changed, 72 insertions, 0 deletions
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