we-promise/sure · error · Provider::Lunchflow::LunchflowError

fetch_failed

fetch_failed

Error message

Failed to fetch data: #{response.code} #{response.message} - #{response.body}

What it means

Fallback branch of Provider::Lunchflow#handle_response (app/models/provider/lunchflow.rb:136-138). Thrown as LunchflowError(:fetch_failed) for any status not in {200, 400, 401, 403, 404, 429}: server errors (500/502/503/504) during Lunchflow incidents, redirects (3xx — HTTParty does not follow redirects by default here, so an http:// base_url redirecting to https lands here), or unusual gateway codes. The message embeds the numeric code, HTTP message, and body, e.g. 'Failed to fetch data: 503 Service Unavailable - ...'.

Source

Thrown at app/models/provider/lunchflow.rb:138

    def handle_response(response)
      case response.code
      when 200
        JSON.parse(response.body, symbolize_names: true)
      when 400
        Rails.logger.error "Lunch Flow API: Bad request - #{response.body}"
        raise LunchflowError.new("Bad request to Lunch Flow API: #{response.body}", :bad_request)
      when 401
        raise LunchflowError.new("Invalid API key", :unauthorized)
      when 403
        raise LunchflowError.new("Access forbidden - check your API key permissions", :access_forbidden)
      when 404
        raise LunchflowError.new("Resource not found", :not_found)
      when 429
        raise LunchflowError.new("Rate limit exceeded. Please try again later.", :rate_limited)
      else
        Rails.logger.error "Lunch Flow API: Unexpected response - Code: #{response.code}, Body: #{response.body}"
        raise LunchflowError.new("Failed to fetch data: #{response.code} #{response.message} - #{response.body}", :fetch_failed)
      end
    end

    class LunchflowError < StandardError
      attr_reader :error_type

      def initialize(message, error_type = :unknown)
        super(message)
        @error_type = error_type
      end
    end
end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Parse the status from the message ('Failed to fetch data: <code> ...') and the log line 'Unexpected response - Code: ...' to identify 5xx vs 3xx.
  2. For 5xx, retry with backoff and check the Lunchflow status page; these are server-side and transient in most cases.
  3. For 3xx codes, change the base_url to https:// so the request is not redirected.
  4. Treat persistent 5xx on all endpoints as an outage: pause the sync and resume on recovery.

Example fix

// before
base_url = 'http://lunchflow.example/api/v1'
client = Provider::Lunchflow.new(key, base_url: base_url)

// after
base_url = 'https://lunchflow.example/api/v1'
client = Provider::Lunchflow.new(key, base_url: base_url)
attempts = 0
begin
  attempts += 1
  client.get_accounts
rescue Provider::Lunchflow::LunchflowError => e
  raise unless e.error_type == :fetch_failed && e.message.match?(/\AFailed to fetch data: 5/) && attempts < 3
  sleep(2**attempts)
  retry
end
Defensive patterns

Strategy: retry

Validate before calling

uri = URI.parse(client.base_url.to_s)
raise ArgumentError, 'use https base_url to avoid 3xx fallback' unless uri.is_a?(URI::HTTPS)

Type guard

def server_error?(e)
  e.is_a?(Provider::Lunchflow::LunchflowError) && e.error_type == :fetch_failed &&
    e.message.match?(/\AFailed to fetch data: 5\d\d/)
end

Try / catch

attempts = 0
begin
  attempts += 1
  client.get_accounts
rescue Provider::Lunchflow::LunchflowError => e
  retryable = e.error_type == :fetch_failed && e.message.match?(/\AFailed to fetch data: 5/)
  raise unless retryable && attempts < 3
  sleep(2**attempts)
  retry
end

Prevention

When it happens

Trigger: Lunchflow upstream outage or deploy returning 5xx; load balancer 502/504 when the origin times out; base_url using http:// so the server answers 301/302 which falls into this branch; custom base_url behind a gateway returning nonstandard codes.

Common situations: Provider maintenance windows caught by scheduled syncs; CDN/gateway mode returning 520-526 (Cloudflare); stale base_url scheme (http) after the provider forced TLS.

Related errors


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