we-promise/sure · error · BrexItem::Syncer::SafeSyncError

Sync failed. Please try again or contact support.

Error message

Sync failed. Please try again or contact support.

What it means

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.

Source

Thrown at app/models/brex_item/syncer.rb:82

      account_ids = linked_accounts
                    .includes(account_provider: :account)
                    .filter_map { |ma| ma.current_account&.id }
      collect_transaction_stats(sync, account_ids: account_ids, source: "brex")
    else
      Rails.logger.info "BrexItem::Syncer - No linked accounts to process"
    end

    # Mark sync health
    collect_health_stats(sync, errors: sync_errors.presence)
  rescue => e
    safe_message = user_safe_error_message(e)
    Rails.logger.error "BrexItem::Syncer - sync failed for Brex item #{brex_item.id}: #{e.class} - #{e.message}"
    Rails.logger.error Array(e.backtrace).first(10).join("\n")
    Sentry.capture_exception(e) do |scope|
      scope.set_tags(brex_item_id: brex_item.id)
    end
    collect_health_stats(sync, errors: [ { message: safe_message, category: "sync_error" } ])
    raise SafeSyncError, safe_message
  end

  def perform_post_sync
    # no-op
  end

  private

    def update_status(sync, key, **options)
      return unless sync.respond_to?(:status_text)

      sync.update!(status_text: I18n.t("brex_items.syncer.#{key}", **options))
    end

    def collect_brex_setup_stats(sync, total_count:, linked_count:, unlinked_count:)
      return {} unless sync.respond_to?(:sync_stats)

      setup_stats = {

View on GitHub (pinned to e69894adb9)

Solutions

  1. Search logs for 'BrexItem::Syncer - sync failed for Brex item <id>' — the following two log lines carry the original error class, message, and backtrace
  2. Look up the same brex_item_id tag in Sentry for the captured exception with full context
  3. Fix the underlying cause (e.g. re-enter the Brex token, wait out a provider incident) rather than handling SafeSyncError itself
  4. At the job/controller layer, rescue SafeSyncError and show e.message to the user — it is already sanitized

Example fix

// caller-side handling of the safe wrapper
begin
  BrexItem::Syncer.new(brex_item).sync
rescue BrexItem::Syncer::SafeSyncError => e
  # e.message is user-safe by construction
  render json: { error: e.message }, status: :bad_request
end
Defensive patterns

Strategy: try-catch

Try / catch

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.

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/bf13faf287d14688. Report an issue: GitHub.