@@ -38,7 +38,7 @@ def rescue_callback(error); end
3838end
3939
4040RSpec . describe "ActiveJob integration" do
41- before ( :all ) do
41+ before ( :each ) do
4242 make_basic_app
4343 end
4444
@@ -58,6 +58,21 @@ def rescue_callback(error); end
5858 MyActiveJob . queue_adapter = :inline
5959 end
6060
61+ it "adds useful context to extra" do
62+ job = FailedJob . new
63+
64+ expect { job . perform_now } . to raise_error ( FailedJob ::TestError )
65+
66+ event = transport . events . last . to_json_compatible
67+ expect ( event . dig ( "extra" , "active_job" ) ) . to eq ( "FailedJob" )
68+ expect ( event . dig ( "extra" , "job_id" ) ) . to be_a ( String )
69+ expect ( event . dig ( "extra" , "provider_job_id" ) ) . to be_nil
70+ expect ( event . dig ( "extra" , "arguments" ) ) . to eq ( [ ] )
71+
72+ expect ( event . dig ( "tags" , "job_id" ) ) . to eq ( event . dig ( "extra" , "job_id" ) )
73+ expect ( event . dig ( "tags" , "provider_job_id" ) ) . to eq ( event . dig ( "extra" , "provider_job_id" ) )
74+ end
75+
6176 it "clears context" do
6277 job = MyActiveJob . new
6378
@@ -70,6 +85,75 @@ def rescue_callback(error); end
7085 expect ( Sentry . get_current_scope . extra ) . to eq ( { } )
7186 end
7287
88+ context "when DeserializationError happens in user's jobs" do
89+ before do
90+ make_basic_app
91+ end
92+
93+ class DeserializationErrorJob < ActiveJob ::Base
94+ def perform
95+ 1 /0
96+ rescue
97+ raise ActiveJob ::DeserializationError
98+ end
99+ end
100+
101+ it "reports the root cause to Sentry" do
102+ expect do
103+ DeserializationErrorJob . perform_now
104+ end . to raise_error ( ActiveJob ::DeserializationError , /divided by 0/ )
105+
106+ expect ( transport . events . size ) . to eq ( 1 )
107+
108+ event = transport . events . last . to_json_compatible
109+ expect ( event . dig ( "exception" , "values" , 0 , "type" ) ) . to eq ( "ZeroDivisionError" )
110+ end
111+
112+ context "and in user-defined reporting job too" do
113+ before do
114+ Sentry . configuration . async = lambda do |event , hint |
115+ UserDefinedReportingJob . perform_now ( event , hint )
116+ end
117+ end
118+
119+ class UserDefinedReportingJob < ActiveJob ::Base
120+ def perform ( event , hint )
121+ Post . find ( 0 )
122+ rescue
123+ raise ActiveJob ::DeserializationError
124+ end
125+ end
126+
127+ it "doesn't cause infinite loop because of excluded exceptions" do
128+ expect do
129+ DeserializationErrorJob . perform_now
130+ end . to raise_error ( ActiveJob ::DeserializationError , /divided by 0/ )
131+ end
132+ end
133+
134+ context "and in customized SentryJob too" do
135+ before do
136+ class CustomSentryJob < ::Sentry ::SendEventJob
137+ def perform ( event , hint )
138+ raise "Not excluded exception"
139+ rescue
140+ raise ActiveJob ::DeserializationError
141+ end
142+ end
143+
144+ Sentry . configuration . async = lambda do |event , hint |
145+ CustomSentryJob . perform_now ( event , hint )
146+ end
147+ end
148+
149+ it "doesn't cause infinite loop" do
150+ expect do
151+ DeserializationErrorJob . perform_now
152+ end . to raise_error ( ActiveJob ::DeserializationError , /divided by 0/ )
153+ end
154+ end
155+ end
156+
73157 context 'using rescue_from' do
74158 it 'does not trigger Sentry' do
75159 job = RescuedActiveJob . new
@@ -83,6 +167,9 @@ def rescue_callback(error); end
83167 end
84168
85169 context "when we are using an adapter which has a specific integration" do
170+ before do
171+ Sentry . configuration . rails . skippable_job_adapters = [ "ActiveJob::QueueAdapters::SidekiqAdapter" ]
172+ end
86173 it "does not trigger sentry and re-raises" do
87174 MyActiveJob . queue_adapter = :sidekiq
88175 job = MyActiveJob . new
0 commit comments