File: active_support/backtrace_cleaner.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: ActiveSupport#1
  class: BacktraceCleaner#17
inherits from
  Object ( Builtin-Module )
has properties
method: initialize #18
method: clean / 1 #23
method: add_filter / 1 #33
method: add_silencer / 1 #44
method: remove_silencers! #50
method: filter / 1 #56
method: silence / 1 #64

Class Hierarchy

Code

   1  module ActiveSupport
   2    # Many backtraces include too much information that's not relevant for the context. This makes it hard to find the signal
   3    # in the backtrace and adds debugging time. With a BacktraceCleaner, you can setup filters and silencers for your particular
   4    # context, so only the relevant lines are included.
   5    #
   6    # If you need to reconfigure an existing BacktraceCleaner, like the one in Rails, to show as much as possible, you can always
   7    # call BacktraceCleaner#remove_silencers!
   8    #
   9    # Example:
  10    #
  11    #   bc = BacktraceCleaner.new
  12    #   bc.add_filter   { |line| line.gsub(Rails.root, '') } 
  13    #   bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
  14    #   bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
  15    #
  16    # Inspired by the Quiet Backtrace gem by Thoughtbot.
  17    class BacktraceCleaner
  18      def initialize
  19        @filters, @silencers = [], []
  20      end
  21      
  22      # Returns the backtrace after all filters and silencers has been run against it. Filters run first, then silencers.
  23      def clean(backtrace)
  24        silence(filter(backtrace))
  25      end
  26 
  27      # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
  28      #
  29      # Example:
  30      #
  31      #   # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
  32      #   backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
  33      def add_filter(&block)
  34        @filters << block
  35      end
  36 
  37      # Adds a silencer from the block provided. If the silencer returns true for a given line, it'll be excluded from the
  38      # clean backtrace.
  39      #
  40      # Example:
  41      #
  42      #   # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
  43      #   backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
  44      def add_silencer(&block)
  45        @silencers << block
  46      end
  47 
  48      # Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as
  49      # you suspect a bug in the libraries you use.
  50      def remove_silencers!
  51        @silencers = []
  52      end
  53 
  54      
  55      private
  56        def filter(backtrace)
  57          @filters.each do |f|
  58            backtrace = backtrace.map { |line| f.call(line) }
  59          end
  60          
  61          backtrace
  62        end
  63        
  64        def silence(backtrace)
  65          @silencers.each do |s|
  66            backtrace = backtrace.reject { |line| s.call(line) }
  67          end
  68          
  69          backtrace
  70        end
  71    end
  72  end