ZhuLinsen/daily_stock_analysis · error · HTTPException

internal_error

internal_error

Error message

图片提取失败

What it means

The catch-all 500 (internal_error, '图片提取失败') for /extract-from-image: any exception from extract_stock_codes_from_image that is not an HTTPException or ValueError — i.e. unexpected failures such as network errors calling the vision LLM API, provider SDK exceptions, or bugs. Full traceback is logged via logger.error with exc_info=True.

Source

Thrown at api/v1/endpoints/stocks.py:192

            detail={"error": "read_failed", "message": "读取上传文件失败"},
        )

    try:
        items, raw_text = extract_stock_codes_from_image(data, content_type)
        extract_items = [
            ExtractItem(code=code, name=name, confidence=conf) for code, name, conf in items
        ]
        codes = [i.code for i in extract_items]
        return ExtractFromImageResponse(
            codes=codes,
            items=extract_items,
            raw_text=raw_text if include_raw else None,
        )
    except ValueError as e:
        raise HTTPException(status_code=400, detail={"error": "extract_failed", "message": str(e)})
    except Exception as e:
        logger.error(f"图片提取失败: {e}", exc_info=True)
        raise HTTPException(
            status_code=500,
            detail={"error": "internal_error", "message": "图片提取失败"},
        )


@router.post(
    "/parse-import",
    response_model=ExtractFromImageResponse,
    responses={
        200: {"description": "解析结果"},
        400: {"description": "未提供数据或解析失败", "model": ErrorResponse},
        500: {"description": "服务器错误", "model": ErrorResponse},
    },
    summary="解析 CSV/Excel/剪贴板",
    description="上传 CSV/Excel 文件或粘贴文本,自动解析股票代码。文件上限 2MB,文本上限 100KB。",
)
async def parse_import(request: Request) -> ExtractFromImageResponse:
    """

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Inspect the server log — the exc_info traceback identifies the exact provider and failure.
  2. Verify outbound connectivity and credentials for the vision provider (curl the provider endpoint from the host).
  3. Retry after transient provider errors; if persistent, check the installed provider SDK version against requirements.txt.
Defensive patterns

Strategy: fallback

Try / catch

try:
    result = await api.extractFromImage(fd)
except ApiError as e:
    if e.code == 'internal_error':
        notify('图片识别服务暂时不可用,请稍后重试或手动输入代码')
        offerManualCodeEntry()  # fallback path
    else:
        raise

Prevention

When it happens

Trigger: Vision provider API unreachable (outbound network blocked, DNS failure, 5xx from Gemini/Anthropic/OpenAI); expired or revoked API key raising a non-ValueError SDK error; provider SDK version incompatibility raising TypeError/AttributeError inside the extractor.

Common situations: Containers without egress to llm provider domains; rate-limit responses surfacing as SDK exceptions; keys rotated after deployment; transient provider outages.

Related errors


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