Skip to content

Commit 71ec4f4

Browse files
Add option to notify Sentry only after the last retry on resque (#2087)
1 parent 65ef04c commit 71ec4f4

File tree

5 files changed

+94
-0
lines changed

5 files changed

+94
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Record client reports for profiles [#2107](https://github.com/getsentry/sentry-ruby/pull/2107)
66
- Adopt Rails 7.1's new BroadcastLogger [#2120](https://github.com/getsentry/sentry-ruby/pull/2120)
7+
- Support sending events after all retries were performed (sentry-resque) [#2087](https://github.com/getsentry/sentry-ruby/pull/2087)
78
- Add [Cron Monitoring](https://docs.sentry.io/product/crons/) support
89
- Add `Sentry.capture_check_in` API for Cron Monitoring [#2117](https://github.com/getsentry/sentry-ruby/pull/2117)
910

sentry-resque/Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ gem 'simplecov'
1414
gem "simplecov-cobertura", "~> 1.4"
1515
gem "rexml"
1616

17+
gem "resque-retry", "~> 1.8"
18+
1719
if RUBY_VERSION.to_f >= 2.6
1820
gem "debug", github: "ruby/debug", platform: :ruby
1921
gem "irb"

sentry-resque/lib/sentry/resque.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ def record(queue, worker, payload, &block)
3232

3333
finish_transaction(transaction, 200)
3434
rescue Exception => exception
35+
klass = payload['class'].constantize
36+
37+
raise if Sentry.configuration.resque.report_after_job_retries &&
38+
defined?(::Resque::Plugins::Retry) == 'constant' &&
39+
klass.is_a?(::Resque::Plugins::Retry) &&
40+
!klass.retry_limit_reached?
41+
3542
::Sentry::Resque.capture_exception(exception, hint: { background: false })
3643
finish_transaction(transaction, 500)
3744
raise

sentry-resque/spec/sentry/resque_spec.rb

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,21 @@ def self.perform
1515
end
1616
end
1717

18+
class FailedRetriableJob
19+
extend Resque::Plugins::Retry
20+
21+
@queue = :default
22+
@retry_limit = 3
23+
24+
def self.perform
25+
1/0
26+
end
27+
end
28+
29+
class FailedZeroRetriesJob < FailedRetriableJob
30+
@retry_limit = 0
31+
end
32+
1833
class TaggedFailedJob
1934
def self.perform
2035
Sentry.set_tags(number: 1)
@@ -125,6 +140,74 @@ def self.perform(msg)
125140
end
126141
end
127142

143+
context "with ResqueRetry" do
144+
context "when report_after_job_retries is true" do
145+
before do
146+
Sentry.configuration.resque.report_after_job_retries = true
147+
end
148+
149+
it "reports exception only on the last run" do
150+
expect do
151+
Resque::Job.create(:default, FailedRetriableJob)
152+
process_job(worker)
153+
end.to change { Resque::Stat.get("failed") }.by(1)
154+
.and change { transport.events.count }.by(0)
155+
156+
expect do
157+
3.times do
158+
process_job(worker)
159+
end
160+
end.to change { transport.events.count }.by(1)
161+
162+
event = transport.events.last.to_hash
163+
164+
expect(event[:sdk]).to eq({ name: "sentry.ruby.resque", version: described_class::VERSION })
165+
expect(event.dig(:exception, :values, 0, :type)).to eq("ZeroDivisionError")
166+
expect(event[:tags]).to eq({ "resque.queue" => "default" })
167+
end
168+
169+
it "reports exception on first run when retry_count is 0" do
170+
expect do
171+
Resque::Job.create(:default, FailedZeroRetriesJob)
172+
process_job(worker)
173+
end.to change { Resque::Stat.get("failed") }.by(1)
174+
.and change { transport.events.count }.by(1)
175+
176+
event = transport.events.last.to_hash
177+
178+
expect(event[:sdk]).to eq({ name: "sentry.ruby.resque", version: described_class::VERSION })
179+
expect(event.dig(:exception, :values, 0, :type)).to eq("ZeroDivisionError")
180+
expect(event[:tags]).to eq({ "resque.queue" => "default" })
181+
end
182+
end
183+
184+
context "when report_after_job_retries is false" do
185+
before do
186+
Sentry.configuration.resque.report_after_job_retries = false
187+
end
188+
189+
it "reports exeception all the runs" do
190+
expect do
191+
Resque::Job.create(:default, FailedRetriableJob)
192+
process_job(worker)
193+
end.to change { Resque::Stat.get("failed") }.by(1)
194+
.and change { transport.events.count }.by(1)
195+
196+
expect do
197+
3.times do
198+
process_job(worker)
199+
end
200+
end.to change { transport.events.count }.by(3)
201+
202+
event = transport.events.last.to_hash
203+
204+
expect(event[:sdk]).to eq({ name: "sentry.ruby.resque", version: described_class::VERSION })
205+
expect(event.dig(:exception, :values, 0, :type)).to eq("ZeroDivisionError")
206+
expect(event[:tags]).to eq({ "resque.queue" => "default" })
207+
end
208+
end
209+
end
210+
128211
context "with ActiveJob" do
129212
require "rails"
130213
require "active_job"

sentry-resque/spec/spec_helper.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "debug" if RUBY_VERSION.to_f >= 2.6 && RUBY_ENGINE == "ruby"
44

55
require "resque"
6+
require "resque-retry"
67

78
# To workaround https://github.com/steveklabnik/mono_logger/issues/13
89
# Note: mono_logger is resque's default logger

0 commit comments

Comments
 (0)