Skip to content

Commit dfc3644

Browse files
Pissardorosa
authored andcommitted
Report rescued recurring enqueue errors to Rails.error
RecurringTask#enqueue rescues Job::EnqueueError (and other-adapter enqueue failures) but forwarded only the message string to the notification payload, never calling Rails.error.report. Reporters subscribed via ActiveSupport::ErrorReporter (Sentry, etc.) therefore never saw recurring enqueue failures — only a log line — so DB write failures during recurring enqueue produced missed ticks with no alerting. Report the rescued exception via Rails.error.report(handled: true) from both the Solid Queue and other-adapter paths, keeping the non-bubbling behavior and the notification payload. This aligns the recurring path with the gem's default on_thread_error reporting. Fixes #746.
1 parent 23100e0 commit dfc3644

2 files changed

Lines changed: 55 additions & 0 deletions

File tree

app/models/solid_queue/recurring_task.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def enqueue(at:)
8686

8787
perform_later.tap do |job|
8888
unless job.successfully_enqueued?
89+
report_enqueue_error(job.enqueue_error, at: at)
8990
payload[:enqueue_error] = job.enqueue_error&.message
9091
end
9192
end
@@ -98,6 +99,7 @@ def enqueue(at:)
9899
payload[:skipped] = true
99100
false
100101
rescue Job::EnqueueError => error
102+
report_enqueue_error(error, at: at)
101103
payload[:enqueue_error] = error.message
102104
false
103105
end
@@ -198,5 +200,11 @@ def enqueue_options
198200
def default_time_zone
199201
SolidQueue.time_zone
200202
end
203+
204+
def report_enqueue_error(error, at:)
205+
if error
206+
Rails.error.report(error, handled: true, source: "application.solid_queue", context: { task: key, at: at })
207+
end
208+
end
201209
end
202210
end

test/models/solid_queue/recurring_task_test.rb

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,46 @@ def perform
307307
end
308308
end
309309

310+
test "reports Job::EnqueueError to Rails.error when enqueuing via Solid Queue" do
311+
SolidQueue::Job.stubs(:create!).raises(ActiveRecord::Deadlocked)
312+
subscriber = ErrorBuffer.new
313+
at = Time.now
314+
315+
with_error_subscriber(subscriber) do
316+
task = recurring_task_with(class_name: "JobWithoutArguments")
317+
task.enqueue(at: at)
318+
end
319+
320+
assert_equal 1, subscriber.errors.count
321+
error, options = subscriber.errors.first
322+
assert_kind_of SolidQueue::Job::EnqueueError, error
323+
assert_match "ActiveRecord::Deadlocked", error.message
324+
assert_equal true, options[:handled]
325+
assert_equal "application.solid_queue", options[:source]
326+
assert_equal "task-id", options[:context][:task]
327+
assert_equal at, options[:context][:at]
328+
end
329+
330+
test "reports enqueue error to Rails.error when using another adapter" do
331+
ActiveJob::QueueAdapters::AsyncAdapter.any_instance.stubs(:enqueue).raises(ActiveJob::EnqueueError.new("All is broken"))
332+
subscriber = ErrorBuffer.new
333+
at = Time.now
334+
335+
with_error_subscriber(subscriber) do
336+
task = recurring_task_with(class_name: "JobUsingAsyncAdapter")
337+
task.enqueue(at: at)
338+
end
339+
340+
assert_equal 1, subscriber.errors.count
341+
error, options = subscriber.errors.first
342+
assert_kind_of ActiveJob::EnqueueError, error
343+
assert_equal "All is broken", error.message
344+
assert_equal true, options[:handled]
345+
assert_equal "application.solid_queue", options[:source]
346+
assert_equal "task-id", options[:context][:task]
347+
assert_equal at, options[:context][:at]
348+
end
349+
310350
private
311351
def with_time_zone(zone)
312352
previous = SolidQueue.time_zone
@@ -344,4 +384,11 @@ def run_all_jobs_inline
344384
worker.start
345385
end
346386
end
387+
388+
def with_error_subscriber(subscriber)
389+
Rails.error.subscribe(subscriber)
390+
yield
391+
ensure
392+
Rails.error.unsubscribe(subscriber) if Rails.error.respond_to?(:unsubscribe)
393+
end
347394
end

0 commit comments

Comments
 (0)