Sidekiq / Airbrake exception only on retries

I would like Airbrake to be notified only of errors when retries are exhausted, but I cannot imagine a way to implement it ...

I can add sidekiq_retries_exhausted hook to send an AirBrake error, but the only way I can catch the actual crashes is to add middleware that swallows the error, but then the operation will be marked as success, if it is not an error ... then never there will be no attempts.

Hope this makes sense!

+4
source share
4 answers

Sidekiq, :

class RaiseOnRetriesExtinguishedMiddleware
    include Sidekiq::Util

  def call(worker, msg, queue)
    yield
  rescue Exception => e
    bubble_exception(msg, e)
  end

  private

  def bubble_exception(msg, e)
    max_retries = msg['retries'] || Sidekiq::Middleware::Server::RetryJobs::DEFAULT_MAX_RETRY_ATTEMPTS
    retry_count = msg['retry_count'] || 0
    last_try = !msg['retry'] || retry_count == max_retries - 1

    raise e if last_try
  end

  def retry_middleware
    @retry_middleware ||= Sidekiq::Middleware::Server::RetryJobs.new
  end
end

, ( Airbrake), . , .

+3

( ):

    Airbrake.configure do |config|
      config.api_key = '...'
      config.ignore_by_filter do |exception_data|
        exception_data[:parameters] && 
        exception_data[:parameters]['retry_count'].to_i > 0
      end
    end
+1

, AirBrake. , :

class TaskWorker
  include Sidekiq::Worker

  class RetryLaterNotAnError < RuntimeError
  end

  def perform task_id
    task = Task.find(task_id)
    task.do_cool_stuff

    if task.finished?
      @log.debug "Nothing to do for task #{task_id}"
      return false
    else
      raise RetryLaterNotAnError, task_id
    end
  end
end

, Airbrake :

Airbrake.configure do |config|
  config.ignore << 'RetryLaterNotAnError'
end

Voila!

0

Bugsnag, Airbrake.

# config/initializers/00_core_ext.rb
class StandardError
  def skip_bugsnag?
    !!@skip_bugsnag
  end

  def skip_bugsnag!
    @skip_bugsnag = true
    return self
  end
end

# config/initializers/bugsnag.rb

  config.ignore_classes << lambda { |e| e.respond_to?(:skip_bugsnag?) && e.skip_bugsnag? }

# In Sidekiq Jobs

raise ErrorToRetryButNotReport.new("some message").skip_bugsnag!

# Or if the error is raised by a third party

begin
  # some code that calls a third-party method
rescue ErrorToRetryButNotReport => e
  e.skip_bugsnag!
  raise
end

sidekiq_retries_exhausted.

0

All Articles