module ExceptionNotifier

Public Class Methods

add_notifier(name, notifier_or_options)
clear_ignore_conditions!() click to toggle source
# File lib/exception_notifier.rb, line 120
def clear_ignore_conditions!
  @@ignores.clear
  @@by_notifier_ignores.clear
end
ignore_crawlers(crawlers) click to toggle source
# File lib/exception_notifier.rb, line 114
def ignore_crawlers(crawlers)
  ignore_if do |_exception, opts|
    opts.key?(:env) && from_crawler(opts[:env], crawlers)
  end
end
ignore_if(&block) click to toggle source

Adds a condition to decide when an exception must be ignored or not.

ExceptionNotifier.ignore_if do |exception, options|
  not Rails.env.production?
end
# File lib/exception_notifier.rb, line 106
def ignore_if(&block)
  @@ignores << block
end
ignore_notifier_if(notifier, &block) click to toggle source
# File lib/exception_notifier.rb, line 110
def ignore_notifier_if(notifier, &block)
  @@by_notifier_ignores[notifier] = block
end
notifiers() click to toggle source
# File lib/exception_notifier.rb, line 97
def notifiers
  @@notifiers.keys
end
notify_exception(exception, options = {}, &block) click to toggle source
# File lib/exception_notifier.rb, line 57
def notify_exception(exception, options = {}, &block)
  return false if ignored_exception?(options[:ignore_exceptions], exception)
  return false if ignored?(exception, options)

  if error_grouping
    errors_count = group_error!(exception, options)
    return false unless send_notification?(exception, errors_count)
  end

  notification_fired = false
  selected_notifiers = options.delete(:notifiers) || notifiers
  [*selected_notifiers].each do |notifier|
    unless notifier_ignored?(exception, options, notifier: notifier)
      fire_notification(notifier, exception, options.dup, &block)
      notification_fired = true
    end
  end

  notification_fired
end
register_exception_notifier(name, notifier_or_options) click to toggle source
# File lib/exception_notifier.rb, line 78
def register_exception_notifier(name, notifier_or_options)
  if notifier_or_options.respond_to?(:call)
    @@notifiers[name] = notifier_or_options
  elsif notifier_or_options.is_a?(Hash)
    create_and_register_notifier(name, notifier_or_options)
  else
    raise ArgumentError, "Invalid notifier '#{name}' defined as #{notifier_or_options.inspect}"
  end
end
Also aliased as: add_notifier
registered_exception_notifier(name) click to toggle source
# File lib/exception_notifier.rb, line 93
def registered_exception_notifier(name)
  @@notifiers[name]
end
testing_mode!() click to toggle source
# File lib/exception_notifier.rb, line 53
def testing_mode!
  self.testing_mode = true
end
unregister_exception_notifier(name) click to toggle source
# File lib/exception_notifier.rb, line 89
def unregister_exception_notifier(name)
  @@notifiers.delete(name)
end

Private Class Methods

create_and_register_notifier(name, options) click to toggle source
# File lib/exception_notifier.rb, line 172
def create_and_register_notifier(name, options)
  notifier_classname = "#{name}_notifier".camelize
  notifier_class = ExceptionNotifier.const_get(notifier_classname)
  notifier = notifier_class.new(options)
  register_exception_notifier(name, notifier)
rescue NameError => e
  raise UndefinedNotifierError,
        "No notifier named '#{name}' was found. Please, revise your configuration options. Cause: #{e.message}"
end
fire_notification(notifier_name, exception, options, &block) click to toggle source
# File lib/exception_notifier.rb, line 159
def fire_notification(notifier_name, exception, options, &block)
  notifier = registered_exception_notifier(notifier_name)
  notifier.call(exception, options, &block)
rescue Exception => e
  raise e if @@testing_mode

  logger.warn(
    "An error occurred when sending a notification using '#{notifier_name}' notifier." \
    "#{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
  )
  false
end
from_crawler(env, ignored_crawlers) click to toggle source
# File lib/exception_notifier.rb, line 182
def from_crawler(env, ignored_crawlers)
  agent = env['HTTP_USER_AGENT']
  Array(ignored_crawlers).any? do |crawler|
    agent =~ Regexp.new(crawler)
  end
end
ignored?(exception, options) click to toggle source
# File lib/exception_notifier.rb, line 127
def ignored?(exception, options)
  @@ignores.any? { |condition| condition.call(exception, options) }
rescue Exception => e
  raise e if @@testing_mode

  logger.warn(
    "An error occurred when evaluating an ignore condition. #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
  )
  false
end
ignored_exception?(ignore_array, exception) click to toggle source
# File lib/exception_notifier.rb, line 153
def ignored_exception?(ignore_array, exception)
  all_ignored_exceptions = (Array(ignored_exceptions) + Array(ignore_array)).map(&:to_s)
  exception_ancestors = exception.singleton_class.ancestors.map(&:to_s)
  !(all_ignored_exceptions & exception_ancestors).empty?
end
notifier_ignored?(exception, options, notifier:) click to toggle source
# File lib/exception_notifier.rb, line 138
    def notifier_ignored?(exception, options, notifier:)
      return false unless @@by_notifier_ignores.key?(notifier)

      condition = @@by_notifier_ignores[notifier]
      condition.call(exception, options)
    rescue Exception => e
      raise e if @@testing_mode

      logger.warn(<<~"MESSAGE")
        An error occurred when evaluating a by-notifier ignore condition. #{e.class}: #{e.message}
        #{e.backtrace.join("\n")}
      MESSAGE
      false
    end