ZhuLinsen/daily_stock_analysis · error · ValueError

Vision API 调用失败,请检查 API Key 与网络: {last_error}

Error message

Vision API 调用失败,请检查 API Key 与网络: {last_error}

What it means

Terminal failure after 3 attempts in extract_stock_codes_from_image: every vision API call raised (network error, auth error, provider 4xx/5xx). The loop retries with exponential backoff (1s, 2s) and random key rotation before giving up; last_error is chained for diagnosis.

Source

Thrown at src/services/image_stock_extractor.py:400

    for attempt in range(3):
        try:
            key = random.choice(keys) if keys else None
            raw = _call_litellm_vision(image_b64, mime_type, api_key=key)
            logger.debug("[ImageExtractor] raw LLM response:\n%s", raw)
            items = _parse_items_from_text(raw)
            logger.info(
                f"[ImageExtractor] {model} 提取 {len(items)} 个: "
                f"{[(i[0], i[1]) for i in items[:5]]}{'...' if len(items) > 5 else ''}"
            )
            return items, raw
        except Exception as e:
            last_error = e
            if attempt < 2:
                delay = 2 ** attempt
                logger.warning(f"[ImageExtractor] 尝试 {attempt + 1}/3 失败,{delay}s 后重试: {e}")
                time.sleep(delay)

    raise ValueError(
        f"Vision API 调用失败,请检查 API Key 与网络: {last_error}"
    ) from last_error

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Inspect the chained last_error (and the [ImageExtractor] warning logs per attempt) to classify: auth vs network vs rate-limit
  2. Verify the API key works with a direct curl to the provider
  3. Check network egress/DNS/proxy from the host running the app
  4. If rate-limited, add more keys for rotation via _get_api_keys_for_model or slow the request rate

Example fix

// not applicable — diagnose via the chained exception and logs
Defensive patterns

Strategy: retry

Try / catch

try:
    items, raw = extract_stock_codes_from_image(b, mime)
except ValueError as e:
    cause = e.__cause__
    if isinstance(cause, (ConnectionError, TimeoutError)):
        schedule_retry_later()
    elif '401' in str(cause) or '403' in str(cause):
        alert_key_rotation_needed()
    else:
        raise

Prevention

When it happens

Trigger: Invalid/revoked API key (401/403); network unreachable/timeout to provider; rate limit exhausted across all attempts; provider outage; wrong base_url (e.g. aihubmix APP-Code header mismatch).

Common situations: Expired or quota-exhausted key; corporate firewall blocking api.openai.com / generativelanguage.googleapis.com; mistyped OPENAI_BASE_URL; provider regional outage.

Related errors


AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15). Data as JSON: /api/errors/8ed749fa62278f10. Report an issue: GitHub.