Sidekiq Retires Exceptions
We wanted some of our sidekiq workers to only report exceptions when they failed on the last retry.
Something like the below was what we where aiming for.
# app/models/my_worker.rb
class MyWorker
include Carbon::Worker
BoomError = Class.new(StandardError)
retry_without_notification BoomError
def call(attributes)
raise BoomError
end
end
Note: Carbon
is an engine which contains shared code applicable to all other
engines in our applications.
Here is what we came up with:
# lib/carbon/worker.rb
module Carbon
module Worker
extend ActiveSupport::Concern
included do
include Sidekiq::Worker
sidekiq_retries_exhausted do |_message, ex|
Rails.logger.info "Sending exception, after final retry, to Sentry: #{ex.inspect}"
::Carbon::ExceptionHandler.capture_exception(ex.cause, message: ex.cause.message)
end
class_attribute :errors_to_retry_without_notification
end
class_methods do
# macro to set exceptions which should be retried without notification to
# exception monitoring.
#
def retry_without_notification(expections)
self.errors_to_retry_without_notification = Array(expections)
end
def method_added(m)
if m == :perform
raise "Do not impliment #perform, use #call instead"
end
end
end
class RetryableError < StandardError; end
def call(*args)
raise NotImplementedError
end
def perform(*args)
call(*args)
rescue *self.class.errors_to_retry_without_notification
raise RetryableError # Raven is configured to ignore this exception
end
end
end
# config/initializers/raven.rb
Raven.configure do |config|
config.excluded_exceptions << "Carbon::Worker::RetryableError"
end
This might be useful to others.