Skip to content

Report rescued recurring enqueue errors to Rails.error#756

Open
rafael-pissardo wants to merge 6 commits into
rails:mainfrom
rafael-pissardo:fix/report-recurring-enqueue-errors-to-rails-error
Open

Report rescued recurring enqueue errors to Rails.error#756
rafael-pissardo wants to merge 6 commits into
rails:mainfrom
rafael-pissardo:fix/report-recurring-enqueue-errors-to-rails-error

Conversation

@rafael-pissardo

Copy link
Copy Markdown

Summary

  • When RecurringTask#enqueue rescues Job::EnqueueError (or an other-adapter enqueue failure), report the exception via Rails.error.report so error subscribers (Sentry, etc.) see it.
  • Keeps the existing non-bubbling behavior (handled: true) and notification payload shape.
  • Fixes a production gap where DB write failures during recurring enqueue only produced log lines / Mission Control “Missed” ticks, with no Issue.

Fixes #746

Test plan

  • bin/rails test test/models/solid_queue/recurring_task_test.rb
  • Recurring enqueue instrumentation tests still pass
  • Confirm a Sentry (or other Rails.error subscriber) receives the original exception object with cause/backtrace during a simulated enqueue failure

Made with Cursor

RecurringTask#enqueue was swallowing Job::EnqueueError (and other-adapter
enqueue failures) without calling Rails.error.report, so production
outages like a read-only primary during failover only produced log lines
and missed Sentry Issues. Align with the gem's on_thread_error default.

Fixes rails#746
@rafael-pissardo
rafael-pissardo force-pushed the fix/report-recurring-enqueue-errors-to-rails-error branch 2 times, most recently from 115d470 to 34098d7 Compare July 17, 2026 19:04
The forked lifecycle test already waits up to shutdown_timeout for the
supervisor PID to exit after repeated TERM signals. The async counterpart
only slept for 1s, which is flaky under load (e.g. Ruby 4 + rails_main + MySQL).
wait_for_jobs_to_finish_for waits on finished_at, which failed jobs never
set, so the test always timed out. Wait for FailedExecution records instead
and stop the worker before asserting to avoid races with in-flight threads.
Setup only waited 0.5s for processes to register, and a few scenarios used
tight pause windows that flake under MySQL CI load. Widen registration and
job-completion waits, and leave more margin so C still finishes last in the
throttled sequence test.
Wait for supervisor teardown to deregister processes, adopt the claimed-
release wait from rails#734, and scope recurring JobResult assertions to the
custom_status rows this test creates so leftover StoreResultJob rows
cannot fail the suite.
Forked StoreResultJob workers from earlier tests can still write after
teardown and overwrite a JobResult whose id was reused, turning status
into "completed". Clear processes/records before creating @Result, wait
for claimed slots before enqueueing blocked jobs, and tighten discard
setup timing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RecurringTask#enqueue does not report rescued Job::EnqueueError to Rails.error

1 participant