我希望Airbrake仅在重试耗尽时收到错误通知,但我似乎无法想出实现它的方法......
我可以添加一个sidekiq_retries_exhausted挂钩来将错误发送到AirBrake,但我能想到捕获实际失败的唯一方法是添加一个吞噬错误的中间件,但是,如果有,那么作业将被标记为成功没有错误...那么永远不会有任何重试..
希望有意义!
答案 0 :(得分: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),否则它不会。这不会影响故障记录,因为这会在链中稍后发生。
答案 1 :(得分:2)
如图所示here(不是我的代码):
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
答案 2 :(得分: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
瞧!
答案 3 :(得分:0)
以下是我们为Bugsnag所做的工作,您可以为Airbrake自定义。
401
然后,您可以手动选择从# 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
发送错误。