class Airbrake::NoticeNotifier

NoticeNotifier is reponsible for sending notices to Airbrake. It supports synchronous and asynchronous delivery.

@see Airbrake::Config The list of options @since v1.0.0 @api public

Constants

DEFAULT_FILTERS

@return [Array<Class>] filters to be executed first

Public Class Methods

new() click to toggle source
# File lib/airbrake-ruby/notice_notifier.rb, line 21
def initialize
  @config = Airbrake::Config.instance
  @filter_chain = FilterChain.new
  @async_sender = AsyncSender.new(:post, self.class.name)
  @sync_sender = SyncSender.new

  DEFAULT_FILTERS.each { |filter| add_filter(filter.new) }

  add_filter(Airbrake::Filters::ContextFilter.new)
  add_filter(Airbrake::Filters::ExceptionAttributesFilter.new)
end

Public Instance Methods

add_filter(filter = nil, &block) click to toggle source

@see Airbrake.add_filte

# File lib/airbrake-ruby/notice_notifier.rb, line 44
def add_filter(filter = nil, &block)
  @filter_chain.add_filter(block_given? ? block : filter)
end
build_notice(exception, params = {}) click to toggle source

@see Airbrake.build_notice

# File lib/airbrake-ruby/notice_notifier.rb, line 54
def build_notice(exception, params = {})
  if @async_sender.closed?
    raise Airbrake::Error,
          "Airbrake is closed; can't build exception: " \
          "#{exception.class}: #{exception}"
  end

  if exception.is_a?(Airbrake::Notice)
    exception[:params].merge!(params)
    exception
  else
    Notice.new(convert_to_exception(exception), params.dup)
  end
end
close() click to toggle source

@see Airbrake.close

# File lib/airbrake-ruby/notice_notifier.rb, line 70
def close
  @sync_sender.close
  @async_sender.close
end
configured?() click to toggle source

@see Airbrake.configured?

# File lib/airbrake-ruby/notice_notifier.rb, line 76
def configured?
  @config.valid?
end
delete_filter(filter_class) click to toggle source

@see Airbrake.delete_filter

# File lib/airbrake-ruby/notice_notifier.rb, line 49
def delete_filter(filter_class)
  @filter_chain.delete_filter(filter_class)
end
has_filter?(filter_class) click to toggle source

@return [Boolean] @since v4.14.0

# File lib/airbrake-ruby/notice_notifier.rb, line 87
def has_filter?(filter_class) # rubocop:disable Naming/PredicateName
  @filter_chain.includes?(filter_class)
end
merge_context(context) click to toggle source

@see Airbrake.merge_context

# File lib/airbrake-ruby/notice_notifier.rb, line 81
def merge_context(context)
  Airbrake::Context.current.merge!(context)
end
notify(exception, params = {}, &block) click to toggle source

@see Airbrake.notify

# File lib/airbrake-ruby/notice_notifier.rb, line 34
def notify(exception, params = {}, &block)
  send_notice(exception, params, default_sender, &block)
end
notify_sync(exception, params = {}, &block) click to toggle source

@see Airbrake.notify_sync

# File lib/airbrake-ruby/notice_notifier.rb, line 39
def notify_sync(exception, params = {}, &block)
  send_notice(exception, params, @sync_sender, &block).value
end

Private Instance Methods

clean_backtrace() click to toggle source
# File lib/airbrake-ruby/notice_notifier.rb, line 131
def clean_backtrace
  caller_copy = Kernel.caller
  clean_bt = caller_copy.drop_while { |frame| frame.include?('/lib/airbrake') }

  # If true, then it's likely an internal library error. In this case return
  # at least some backtrace to simplify debugging.
  return caller_copy if clean_bt.empty?

  clean_bt
end
convert_to_exception(ex) click to toggle source
# File lib/airbrake-ruby/notice_notifier.rb, line 93
def convert_to_exception(ex)
  if ex.is_a?(Exception) || Backtrace.java_exception?(ex)
    # Manually created exceptions don't have backtraces, so we create a fake
    # one, whose first frame points to the place where Airbrake was called
    # (normally via `notify`).
    ex.set_backtrace(clean_backtrace) unless ex.backtrace
    return ex
  end

  e = RuntimeError.new(ex.to_s)
  e.set_backtrace(clean_backtrace)
  e
end
default_sender() click to toggle source
# File lib/airbrake-ruby/notice_notifier.rb, line 121
def default_sender
  return @async_sender if @async_sender.has_workers?

  logger.warn(
    "#{LOG_LABEL} falling back to sync delivery because there are no " \
    "running async workers",
  )
  @sync_sender
end
send_notice(exception, params, sender) { |notice| ... } click to toggle source
# File lib/airbrake-ruby/notice_notifier.rb, line 107
def send_notice(exception, params, sender)
  promise = @config.check_configuration
  return promise if promise.rejected?

  notice = build_notice(exception, params)
  yield notice if block_given?
  @filter_chain.refine(notice)

  promise = Airbrake::Promise.new
  return promise.reject("#{notice} was marked as ignored") if notice.ignored?

  sender.send(notice, promise)
end