we-promise/sure · error · Provider::YahooFinance::Error

Failed to fetch security prices: #{prices_response.error.mes

Error message

Failed to fetch security prices: #{prices_response.error.message}

What it means

Provider::YahooFinance::Error raised inside fetch_security_price when the delegated fetch_security_prices call (a 10-day window ending at the target date) returned a failed ProviderResponse. The message wraps the inner error — the real cause is whatever broke the range fetch (rate limit, missing chart data, invalid JSON from Yahoo).

Source

Thrown at app/models/provider/yahoo_finance.rb:305

  def fetch_security_price(symbol:, exchange_operating_mic: nil, date:)
    with_provider_response do
      symbol = normalize_symbol(symbol, exchange_operating_mic)
      cache_key = "security_price_#{symbol}_#{exchange_operating_mic}_#{date}"
      if cached_result = get_cached_result(cache_key)
        cached_result
      else
        # For a single date, we'll fetch a range and find the closest match
        end_date = date
        start_date = date - 10.days # Extended range for better coverage

        prices_response = fetch_security_prices(
          symbol: symbol,
          exchange_operating_mic: exchange_operating_mic,
          start_date: start_date,
          end_date: end_date
        )

        raise Error, "Failed to fetch security prices: #{prices_response.error.message}" unless prices_response.success?

        prices = prices_response.data
        if prices.length == 1
          target_price = prices.first
        else
          # Find the exact date or the closest previous date
          target_price = prices.find { |p| p.date == date } ||
                        prices.select { |p| p.date <= date }.max_by(&:date)

          raise Error, "No price found for #{symbol} on or before #{date}" unless target_price
        end

        cache_result(cache_key, target_price)
        target_price
      end
    end
  end

View on GitHub (pinned to e69894adb9)

Solutions

  1. Read the wrapped message to find the root cause and fix that ('No chart data', 'Invalid response format', rate-limit text)
  2. For rate-limit causes, back off (health_status tracks rate_limited for 30 min) and retry the batch later with pacing
  3. For missing-chart causes, verify the symbol on Yahoo and re-fetch via search_securities to get the canonical form
  4. Cache single-date prices (already 5-min cached) and reduce redundant calls during syncs

Example fix

// before
price = provider.fetch_security_price(symbol: "ASML.AS", exchange_operating_mic: "XAMS", date: d)

// after
begin
  price = provider.fetch_security_price(symbol: "ASML.AS", exchange_operating_mic: "XAMS", date: d)
rescue Provider::YahooFinance::Error => e
  if provider.health_status == :rate_limited
    RetryablePriceSyncJob.perform_later(wait: 10.minutes)
  else
    price = fallback_provider.fetch_security_price(symbol: "ASML.AS", exchange_operating_mic: "XAMS", date: d)
  end
end
Defensive patterns

Strategy: try-catch

Try / catch

begin
  provider.fetch_security_price(symbol:, exchange_operating_mic:, date:)
rescue Provider::YahooFinance::Error => e
  if provider.health_status == :rate_limited
    RetryablePriceJob.perform_later(wait: 10.minutes)
  else
    fallback_provider.fetch_security_price(symbol:, exchange_operating_mic:, date:)
  end
end

Prevention

When it happens

Trigger: fetch_security_price(symbol:, date:) on a cache miss delegates to fetch_security_prices for a 10-day chart window; that inner call hit Yahoo rate limiting, returned no chart data for the symbol, or returned non-JSON — and this wrapper propagates its message.

Common situations: Bulk price backfills tripping Yahoo's unofficial rate limits; obscure tickers Yahoo doesn't chart; Yahoo endpoint changes breaking parsing; datacenter IP blocks.

Related errors


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