we-promise/sure · error · Provider::Snaptrade::ApiError

SnapTrade server error (#{response.status}). Please try agai

Error message

SnapTrade server error (#{response.status}). Please try again later.

What it means

Raised by Provider::Snaptrade.handle_response when the SnapTrade API answers HTTP 5xx. The message includes the exact status; the ApiError carries status_code and response_body. Like the SimpleFIN counterpart, this means the request reached SnapTrade and its server failed - transient upstream trouble, not an app bug.

Source

Thrown at app/models/provider/snaptrade.rb:392

      if response.success?
        return {} if response.body.blank?
        begin
          JSON.parse(response.body)
        rescue JSON::ParserError
          raise ApiError.new("SnapTrade API error (#{operation}): invalid JSON response",
                             status_code: response.status, response_body: response.body)
        end
      else
        Rails.logger.error("SnapTrade API error (#{operation}): #{response.status}")
        case response.status
        when 401, 403
          mark_requires_update!
          raise AuthenticationError, "Authentication failed (#{operation}): HTTP #{response.status}"
        when 429
          raise ApiError.new("Rate limit exceeded. Please try again later.",
                             status_code: response.status, response_body: response.body)
        when 500..599
          raise ApiError.new("SnapTrade server error (#{response.status}). Please try again later.",
                             status_code: response.status, response_body: response.body)
        else
          raise ApiError.new("SnapTrade API error (#{operation}): HTTP #{response.status}",
                             status_code: response.status, response_body: response.body)
        end
      end
    end

    def api_connection
      @api_connection ||= Faraday.new do |faraday|
        faraday.options.timeout = 30
        faraday.options.open_timeout = 10
      end
    end

    def with_retries(operation_name, max_retries: MAX_RETRIES)
      retries = 0

View on GitHub (pinned to e69894adb9)

Solutions

  1. Retry later with backoff - most 5xx from SnapTrade resolve within minutes
  2. Check the response_body on the error and the SnapTrade status page for an incident
  3. If only one account errors while others sync, the underlying broker (not SnapTrade-wide) is the problem - still just wait
  4. Keep the previous snapshot and surface 'sync temporarily unavailable' rather than failing hard
Defensive patterns

Strategy: retry

Try / catch

begin
  snaptrade.get_balances(account_id: id)
rescue Provider::Snaptrade::ApiError => e
  if (500..599).cover?(e.status_code.to_i)
    schedule_retry(minutes: 15) # upstream transient; keep last snapshot
  else
    raise
  end
end

Prevention

When it happens

Trigger: Any SnapTrade API call returning 500/502/503/504 - commonly during broker outages behind SnapTrade (the upstream institution's API failing), SnapTrade deployments, or overload during market-open traffic spikes.

Common situations: Weekend maintenance windows; a specific brokerage integration inside SnapTrade failing so only that institution's accounts error; retrying after a few minutes succeeds; correlates with SnapTrade status incidents.

Related errors


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