module Airbrake::Filters::KeysFilter

def call(notice)

Other tags:
    See: FilterChain -

Returns:
  • (void) -

Parameters:
  • notice (Notice) -- the notice to be filtered
def call(notice)
  unless @valid_patterns
    eval_proc_patterns!
    validate_patterns
  end
  FILTERABLE_KEYS.each do |key|
    notice[key] = filter_hash(notice[key])
  end
  FILTERABLE_CONTEXT_KEYS.each { |key| filter_context_key(notice, key) }
  return unless notice[:context][:url]
  filter_url(notice)
end

def eval_proc_patterns!

def eval_proc_patterns!
  return unless @patterns.any? { |pattern| pattern.is_a?(Proc) }
  @patterns = @patterns.flat_map do |pattern|
    next(pattern) unless pattern.respond_to?(:call)
    pattern.call
  end
end

def filter_context_key(notice, key)

def filter_context_key(notice, key)
  return unless notice[:context][key]
  return if notice[:context][key] == FILTERED
  unless should_filter?(key)
    return notice[:context][key] = filter_hash(notice[:context][key])
  end
  notice[:context][key] = FILTERED
end

def filter_hash(hash) # rubocop:disable Metrics/AbcSize

rubocop:disable Metrics/AbcSize
def filter_hash(hash) # rubocop:disable Metrics/AbcSize
  return hash unless hash.is_a?(Hash)
  hash_copy = hash.dup
  hash.each_key do |key|
    if should_filter?(key.to_s)
      hash_copy[key] = FILTERED
    elsif hash_copy[key].is_a?(Hash)
      hash_copy[key] = filter_hash(hash_copy[key])
    elsif hash[key].is_a?(Array)
      hash_copy[key].each_with_index do |h, i|
        hash_copy[key][i] = filter_hash(h)
      end
    end
  end
  hash_copy
end

def filter_url(notice)

def filter_url(notice)
  begin
    url = URI(notice[:context][:url])
  rescue URI::InvalidURIError
    return
  end
  return unless url.query
  notice[:context][:url] = filter_url_params(url)
end

def filter_url_params(url)

def filter_url_params(url)
  url.query = URI.decode_www_form(url.query).to_h.map do |key, val|
    should_filter?(key) ? "#{key}=[Filtered]" : "#{key}=#{val}"
  end.join('&')
  url.to_s
end

def initialize(patterns)

Parameters:
  • patterns (Array) --
def initialize(patterns)
  @patterns = patterns
  @valid_patterns = false
end

def should_filter?(_key)

Raises:
  • (NotImplementedError) - if called directly
def should_filter?(_key)
  raise NotImplementedError, 'method must be implemented in the included class'
end

def validate_patterns

def validate_patterns
  @valid_patterns = @patterns.all? do |pattern|
    VALID_PATTERN_CLASSES.any? { |c| pattern.is_a?(c) }
  end
  return if @valid_patterns
  logger.error(
    "#{LOG_LABEL} one of the patterns in #{self.class} is invalid. " \
    "Known patterns: #{@patterns}",
  )
end