我希望 Airbrake 仅在重试用尽时才收到错误通知,但我似乎想不出一种方法来实现它......
我可以添加一个 sidekiq_retries_exhausted 挂钩以将错误发送到 AirBrake,但我能想到捕获实际失败的唯一方法是添加一个吞下错误的中间件,但是如果没有错误,该作业将被标记为成功...那么永远不会有任何重试..
希望这是有道理的!
我希望 Airbrake 仅在重试用尽时才收到错误通知,但我似乎想不出一种方法来实现它......
我可以添加一个 sidekiq_retries_exhausted 挂钩以将错误发送到 AirBrake,但我能想到捕获实际失败的唯一方法是添加一个吞下错误的中间件,但是如果没有错误,该作业将被标记为成功...那么永远不会有任何重试..
希望这是有道理的!
我设法使用插入列表开头的 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),否则它不会。这不会影响失败记录,因为这会在链的后面发生。
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
我遇到了完全相同的事情,并想让它远离 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
瞧!
这是我们为 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
.