From 2181e70221b2513acae657014b6ecaaab63b2f58 Mon Sep 17 00:00:00 2001 From: Ben Hutton Date: Mon, 23 Dec 2024 16:55:45 -0500 Subject: [PATCH] Use attempt_threshold to skip reporting on first N attempts --- CHANGELOG.md | 1 + .../lib/sentry/sidekiq/error_handler.rb | 13 ++++++ sentry-sidekiq/spec/sentry/sidekiq_spec.rb | 41 +++++++++++++++---- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd18e7413..02dccd6a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Features - Improve the accuracy of duration calculations in cron jobs monitoring ([#2471](https://github.com/getsentry/sentry-ruby/pull/2471)) +- Use attempt_threshold to skip reporting on first N attempts ([#2503](https://github.com/getsentry/sentry-ruby/pull/2503)) ### Bug fixes diff --git a/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb b/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb index 50c720929..64659df1e 100644 --- a/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb +++ b/sentry-sidekiq/lib/sentry/sidekiq/error_handler.rb @@ -31,6 +31,19 @@ def call(ex, context, sidekiq_config = nil) end end + # Check if the retry count is below the attempt_threshold + attempt_threshold = context.dig(:job, "attempt_threshold") + if attempt_threshold && retryable?(context) + attempt_threshold = attempt_threshold.to_i + retry_count = context.dig(:job, "retry_count") + # attempt 1 - retry_count is nil + # attempt 2 - this is your first retry so retry_count is 0 + # attempt 3 - you have retried once, retry_count is 1 + attempt = retry_count.nil? ? 1 : retry_count.to_i + 2 + + return if attempt < attempt_threshold + end + Sentry::Sidekiq.capture_exception( ex, contexts: { sidekiq: context_filter.filtered }, diff --git a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb index 4c788c9ce..110ea850a 100644 --- a/sentry-sidekiq/spec/sentry/sidekiq_spec.rb +++ b/sentry-sidekiq/spec/sentry/sidekiq_spec.rb @@ -109,18 +109,45 @@ expect(retry_set.count).to eq(1) end + def retry_last_failed_job + retry_set.first.add_to_queue + job = queue.first + work = Sidekiq::BasicFetch::UnitOfWork.new('queue:default', job.value) + process_work(processor, work) + end + + context "with attempt_threshold" do + it "doesn't report the error until attempts equal the threshold" do + worker = Class.new(SadWorker) + worker.sidekiq_options attempt_threshold: 3 + + execute_worker(processor, worker) + expect(transport.events.count).to eq(0) + + retry_last_failed_job + expect(transport.events.count).to eq(0) + + retry_last_failed_job + expect(transport.events.count).to eq(1) + end + + it "doesn't report the error when threshold is not reached" do + worker = Class.new(SadWorker) + worker.sidekiq_options attempt_threshold: 3 + + execute_worker(processor, worker) + expect(transport.events.count).to eq(0) + + retry_last_failed_job + expect(transport.events.count).to eq(0) + end + end + context "with config.report_after_job_retries = true" do before do Sentry.configuration.sidekiq.report_after_job_retries = true end - def retry_last_failed_job - retry_set.first.add_to_queue - job = queue.first - work = Sidekiq::BasicFetch::UnitOfWork.new('queue:default', job.value) - process_work(processor, work) - end - context "when retry: is specified" do it "doesn't report the error until retries are exhuasted" do worker = Class.new(SadWorker)