{"record":{"id":"bf13faf287d14688","repo":"we-promise/sure","slug":"sync-failed-please-try-again-or-contact-support","errorCode":null,"errorMessage":"Sync failed. Please try again or contact support.","messagePattern":"Sync failed\\. Please try again or contact support\\.","errorType":"exception","errorClass":"BrexItem::Syncer::SafeSyncError","httpStatus":null,"severity":"error","filePath":"app/models/brex_item/syncer.rb","lineNumber":82,"sourceCode":"      account_ids = linked_accounts\n                    .includes(account_provider: :account)\n                    .filter_map { |ma| ma.current_account&.id }\n      collect_transaction_stats(sync, account_ids: account_ids, source: \"brex\")\n    else\n      Rails.logger.info \"BrexItem::Syncer - No linked accounts to process\"\n    end\n\n    # Mark sync health\n    collect_health_stats(sync, errors: sync_errors.presence)\n  rescue => e\n    safe_message = user_safe_error_message(e)\n    Rails.logger.error \"BrexItem::Syncer - sync failed for Brex item #{brex_item.id}: #{e.class} - #{e.message}\"\n    Rails.logger.error Array(e.backtrace).first(10).join(\"\\n\")\n    Sentry.capture_exception(e) do |scope|\n      scope.set_tags(brex_item_id: brex_item.id)\n    end\n    collect_health_stats(sync, errors: [ { message: safe_message, category: \"sync_error\" } ])\n    raise SafeSyncError, safe_message\n  end\n\n  def perform_post_sync\n    # no-op\n  end\n\n  private\n\n    def update_status(sync, key, **options)\n      return unless sync.respond_to?(:status_text)\n\n      sync.update!(status_text: I18n.t(\"brex_items.syncer.#{key}\", **options))\n    end\n\n    def collect_brex_setup_stats(sync, total_count:, linked_count:, unlinked_count:)\n      return {} unless sync.respond_to?(:sync_stats)\n\n      setup_stats = {","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/brex_item/syncer.rb#L64-L100","documentation":"BrexItem::Syncer wraps ANY exception raised during a Brex sync into SafeSyncError carrying a sanitized, user-facing message ('Sync failed. Please try again or contact support.'). This is a catch-all boundary, not a specific failure: the real cause is logged (error class, message, first 10 backtrace lines) and sent to Sentry tagged with brex_item_id. Seeing this error means looking past it to the wrapped exception.","triggerScenarios":"Any error inside the sync flow: a 401 from the Brex client for an invalid/expired token, network timeouts, unexpected response payloads, or crashes while processing accounts/transactions. The rescue at the end of the sync converts each into raise SafeSyncError, safe_message.","commonSituations":"Brex token revoked or rotated; Brex API outage or schema change; transient network failure during a scheduled sync job; data-specific crashes that only one family's payload triggers.","solutions":["Search logs for 'BrexItem::Syncer - sync failed for Brex item <id>' — the following two log lines carry the original error class, message, and backtrace","Look up the same brex_item_id tag in Sentry for the captured exception with full context","Fix the underlying cause (e.g. re-enter the Brex token, wait out a provider incident) rather than handling SafeSyncError itself","At the job/controller layer, rescue SafeSyncError and show e.message to the user — it is already sanitized"],"exampleFix":"// caller-side handling of the safe wrapper\nbegin\n  BrexItem::Syncer.new(brex_item).sync\nrescue BrexItem::Syncer::SafeSyncError => e\n  # e.message is user-safe by construction\n  render json: { error: e.message }, status: :bad_request\nend","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"rescue BrexItem::Syncer::SafeSyncError => e at the job/controller boundary; show e.message (pre-sanitized) and rely on the pre-written logs/Sentry tag brex_item_id for diagnosis. Never rescue-and-retry blindly — the wrapped cause may be a permanent 401.","preventionTips":["Keep the Brex token current; watch for token-revocation 401s in logs","Correlate via the brex_item_id Sentry tag when a sync fails","Treat this wrapper as the single user-facing failure point; investigate the logged original class/message"],"tags":["brex","sync","error-wrapping","sentry","background-jobs"],"backgroundTag":"provider-sync-failed","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}