From 8ddea11599c7d0f12c8acdcbc9d6237b06b12a1f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 24 Mar 2026 13:57:08 +0000 Subject: [PATCH] Tighten retry exhaustion state handling Co-authored-by: jjmata <187772+jjmata@users.noreply.github.com> Agent-Logs-Url: https://github.com/we-promise/sure/sessions/ea7a06f4-8344-4a00-877a-eda8cdfdc16a --- app/models/sync.rb | 5 +++-- test/models/sync_test.rb | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/app/models/sync.rb b/app/models/sync.rb index ba19bac01..faccac42b 100644 --- a/app/models/sync.rb +++ b/app/models/sync.rb @@ -108,7 +108,7 @@ class Sync < ApplicationRecord # Retry exhaustion can leave the sync in `pending` because we reset it # after each rate-limit error to make the next ActiveJob retry retryable. start! if pending? - fail! if may_fail? + fail! update!(error: error_message) end @@ -167,7 +167,8 @@ class Sync < ApplicationRecord def reset_for_retry! # We intentionally bypass callbacks/state events here so the same sync record # can become retryable again without firing post-sync hooks or extra - # transition side effects while the job is being retried. + # transition side effects while the TwelveData rate-limit error is being + # re-raised back to `SyncJob.retry_on`. update_columns( status: "pending", error: nil, diff --git a/test/models/sync_test.rb b/test/models/sync_test.rb index ecb78f816..ae9c515a9 100644 --- a/test/models/sync_test.rb +++ b/test/models/sync_test.rb @@ -76,6 +76,18 @@ class SyncTest < ActiveSupport::TestCase assert_not_nil sync.failed_at end + test "fail_for_retry_exhaustion! marks syncing sync as failed" do + sync = Sync.create!(syncable: accounts(:depository)) + sync.start! + + sync.fail_for_retry_exhaustion!("rate limited too many times") + + sync.reload + assert_equal "failed", sync.status + assert_equal "rate limited too many times", sync.error + assert_not_nil sync.failed_at + end + test "can run nested syncs that alert the parent when complete" do family = families(:dylan_family) plaid_item = plaid_items(:one)