From f42c77f927eb49b00e84d355e07de48723d03fcb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 22 Nov 2008 18:06:08 +0100 Subject: Added ActiveSupport::BacktraceCleaner and Rails::BacktraceCleaner for cutting down on backtrace noise (inspired by the Thoughtbot Quiet Backtrace plugin) [DHH] --- .../lib/active_support/backtrace_cleaner.rb | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 activesupport/lib/active_support/backtrace_cleaner.rb (limited to 'activesupport/lib/active_support/backtrace_cleaner.rb') 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 -- cgit v1.2.3