ZhuLinsen/daily_stock_analysis · warning · HTTPException

not_found

not_found

Error message

未找到 id/query_id={record_id} 的分析记录

What it means

The history share-image pipeline resolves a record by id or query_id via HistoryService.resolve_and_get_detail; a None result raises HTTP 404 code=not_found '未找到 id/query_id={record_id} 的分析记录' (history.py:97-105). This helper feeds both the PNG and desktop-HTML share renderers, so any share URL with an unresolvable record fails here before rendering.

Source

Thrown at api/v1/endpoints/history.py:97

        if isinstance(context_snapshot, Mapping):
            market_payload = context_snapshot.get("market_review_payload")
            if isinstance(market_payload, Mapping):
                return market_payload

    raw_result = result.get("raw_result")
    return raw_result if isinstance(raw_result, Mapping) else None


def _history_share_image_input(
    record_id: str,
    db_manager: DatabaseManager,
) -> tuple[Mapping[str, Any], str]:
    """Load the shared persisted input used by PNG and desktop HTML renderers."""

    service = HistoryService(db_manager)
    result = service.resolve_and_get_detail(record_id)
    if result is None:
        raise HTTPException(
            status_code=404,
            detail={
                "error": "not_found",
                "message": f"未找到 id/query_id={record_id} 的分析记录",
            },
        )

    try:
        markdown_content = service.get_markdown_report(record_id)
    except MarkdownReportGenerationError as exc:
        logger.error("Share image report generation failed for %s: %s", record_id, exc.message)
        raise HTTPException(
            status_code=500,
            detail={
                "error": "generation_failed",
                "message": f"生成分享图片所需报告失败: {exc.message}",
            },
        ) from exc

View on GitHub (pinned to 5159bd72e8)

Solutions

  1. Verify the record exists first: GET the history detail endpoint for the same record_id and confirm a 200
  2. If sharing is expected to outlive deletions, export/render the image before deleting the record, or persist the rendered artifact separately
  3. Align environments: ensure the share URL targets the same server/DB that produced the record id
  4. Sanitize record_id client-side (numeric id or full query_id) before building share links

Example fix

# before
img = requests.get(f"{base}/history/{record_id}/share-image")
img.raise_for_status()

# after
detail = requests.get(f"{base}/history/{record_id}")
if detail.status_code == 404:
    raise FileNotFoundError(f"history record {record_id} gone; cannot share")
img = requests.get(f"{base}/history/{record_id}/share-image")
img.raise_for_status()
Defensive patterns

Strategy: validation

Validate before calling

# Resolve via the detail endpoint before requesting the share artifact
import requests

def ensure_shareable(record_id: str) -> dict:
    r = requests.get(f"{BASE}/api/v1/history/{record_id}")
    if r.status_code == 404:
        raise FileNotFoundError(f"record {record_id} no longer exists")
    r.raise_for_status()
    return r.json()

Type guard

def is_history_record_missing(resp) -> bool:
    return (
        resp.status_code == 404
        and isinstance(resp.json().get('detail'), dict)
        and resp.json()['detail'].get('error') == 'not_found'
        and '分析记录' in resp.json()['detail'].get('message', '')
    )

Try / catch

try:
    img = get_share_image(record_id)
except HTTPError as e:
    if is_history_record_missing(e.response):
        invalidate_share_link(record_id)  # stop offering a dead share
    else:
        raise

Prevention

When it happens

Trigger: GET share-image endpoints where record_id is neither a numeric history id nor a known query_id; record deleted between listing and share-image fetch; wrong DB (record created in another environment); id typos or truncated UUIDs in hand-built share links.

Common situations: Desktop/Web share links pointing at a server with a different database (e.g. local vs deployed); user deletes history then opens an old share URL; records pruned by retention cleanup; copy/paste corruption of the query_id part of share URLs.

Related errors


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