5

我希望 Airbrake 仅在重试用尽时才收到错误通知,但我似乎想不出一种方法来实现它......

我可以添加一个 sidekiq_retries_exhausted 挂钩以将错误发送到 AirBrake,但我能想到捕获实际失败的唯一方法是添加一个吞下错误的中间件,但是如果没有错误,该作业将被标记为成功...那么永远不会有任何重试..

希望这是有道理的!

4

4 回答 4

4

我设法使用插入列表开头的 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),否则它不会。这不会影响失败记录,因为这会在链的后面发生。

于 2013-10-30T15:39:43.070 回答
3

As shown here (not my code):

    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
于 2013-10-30T14:27:16.510 回答
2

我遇到了完全相同的事情,并想让它远离 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

瞧!

于 2015-08-25T18:53:24.303 回答
1

这是我们为 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.

于 2017-04-19T15:50:31.537 回答