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.